У меня есть пользовательская система, которая работает хорошо, пока я не пытаюсь получить информацию, если я слежу за пользователем, но она просто не работает. Вот пример кода.
Что не так
В serializers.py
пользователя я пытаюсь проверить, следует ли зарегистрированному пользователю текущий пользователь, он проверяет. Я попытался установить один из 3 ответов: True
, False
или "not following"
. Я делаю это в пользовательском сериализаторе, поэтому API может отображать некоторые вещи в зависимости от значения.
Несколько замечаний о том, как следовать и отменять подписку в этом приложении
Статус играет Огромная роль здесь, есть три статуса, на данный момент, followed
, unfollowed
и blocked
. Когда пользователь следует, статус устанавливается на followed
при создании, при отмене подписки пользователь не удаляется, а вместо этого статус изменяется на unfollowed
, он был разработан таким образом, чтобы сохранять больше данных, таких как время после завершения и остальные.
Что происходит, когда я запускаю приведенный ниже код
Когда я запускаю код, он узнает себя при просмотре своего профиля и возвращает соответствующее сообщение, но когда я просматриваю пользователя, я следую, Я получаю response1 . в этом ответе, поскольку я получаю "not following"
вместо True
/ False
, это означает, что блок try
вышел из строя.
Я также заметил, что если в сериализаторе в get_am_i_following()
функция, которую я изменяю filter(slug=user.slug)
на filter(pk=user.pk)
, запускается, но я получаю False
(как показано в response2 ниже), когда на самом деле я должен получить True
.
models.py
class User(AbstractBaseUser, PermissionsMixin):
username = None
email = models.EmailField(max_length=254, unique=True)
fullname = models.CharField(max_length=250)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
last_login = models.DateTimeField(null=True, blank=True)
date_joined = models.DateTimeField(auto_now_add=True)
slug = models.SlugField(max_length=255, unique=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['fullname']
objects = UserManager()
def __str__(self):
return self.email
def follow_a_user(self, user_to_follow):
# find user by slug
try:
user_to_follow = User.objects.get(slug=user_to_follow)
except:
return False, 'User not found'
if user_to_follow != self:
try:
log = FollowLog.objects.get(
user=user_to_follow,
followed_by=self,
)
log.set_as_followed()
return True, 'Refollow successful'
except:
FollowLog.objects.create(
user=user_to_follow,
followed_by=self,
status=FollowStatus.following.value
)
return True, 'Follow Successful'
else:
return False, 'Cannot follow oneself'
def unfollow_a_user(self, user_to_unfollow):
# find user by slug
try:
user_to_unfollow = User.objects.get(slug=user_to_unfollow)
except:
return False, 'User not found'
if user_to_unfollow != self:
try:
log = FollowLog.objects.get(
user=user_to_unfollow,
followed_by=self,
)
log.set_as_unfollowed()
return True, 'UnFollow Successful'
except Exception as e:
return False, 'User doesnt follow the specified user' if 'exist' in e else e
else:
return False, 'Cannot unfollow oneself'
class FollowStatus(enum.Enum):
following = 'following'
unfollowed = 'unfollowed'
blocked = 'blocked'
FOLLOW_STATUS = (
('following', 'following'),
('unfollowed', 'unfollowed'),
('blocked', 'blocked'),
)
class FollowLog(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='followers')
followed_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,
related_name='following', null=True)
followed_on = models.DateTimeField(auto_now_add=True)
status = models.CharField(choices=FOLLOW_STATUS, default=FollowStatus.following.value, max_length=30)
updated_on = models.DateTimeField(auto_now=True)
unfollowed_on = models.DateTimeField(null=True)
blocked_on = models.DateTimeField(null=True)
def __str__(self):
return "{} followed by {} ".format(self.user, self.followed_by)
def set_as_followed(self):
self.status = FollowStatus.following.value
self.save()
def set_as_blocked(self):
self.status = FollowStatus.blocked.value
self.blocked_on = timezone.now()
self.save()
def set_as_unfollowed(self):
self.status = FollowStatus.unfollowed.value
self.unfollowed_on = timezone.now()
self.save()
serializers.py
Это место, где я пытаюсь заставить волхвов c произойти, где я возвращаю утверждения, если пользователь (вошедший в систему) следует за другим пользователем, мы проверяем его профиль. Мы делаем это с помощью функции get_am_i_following
.
class CustomUserDetailsSerializer(serializers.ModelSerializer):
'''
a custom serializer for
the user to view his own data
'''
profiles = ProfileSerializer(read_only=True, many=True)
showcase = ShowcaseSlugSerializer(read_only=True, many=True)
followers_count = serializers.SerializerMethodField(read_only=True)
following_count = serializers.SerializerMethodField(read_only=True)
am_i_following = serializers.SerializerMethodField(read_only=True)
class Meta:
model = User
fields = ('pk','email', 'fullname', 'profiles', 'slug', 'showcase', 'followers_count', 'following_count', 'am_i_following')
read_only_fields = ('email', 'fullname', 'profiles', 'slug', 'showcase')
def get_followers_count(self, instance):
return instance.followers.all().filter(status='following').count()
def get_following_count(self, instance):
return instance.following.all().filter(status='following').count()
def get_am_i_following(self, instance):
'''
returns =
(
Myself- when the user i am checking if i follow, is myself
following- when i am following user
not following- when user isnt following or when not logged in
)
'''
try:
request = self.context.get("request")
user = request.user
if user==instance:
return 'Myself'
else:
return instance.followers.filter(status='following').filter(slug=user.slug).exists()
except Exception as e:
print(e)
return "not following"
views.py
class UserRetriveAPIView(APIView):
'''
Gets a particular user in the database using the slug as the lookup
'''
serializer_class = CustomUserDetailsSerializer
permission_classes = [IsAuthenticatedOrReadOnly, IsUserOrReadOnly]
def get(self, request, slug):
user = get_object_or_404(User, slug=slug)
serializer_context = {"request": request}
serializer = self.serializer_class(user, context=serializer_context)
return Response(serializer.data, status=status.HTTP_200_OK)
urls.py
path("users/<slug:slug>/", UserRetriveAPIView.as_view(), name="users-detail")
Обычно при выполнении кода, когда filter(slug=user.slug)
в функции get_am_i_following
дает мне JSON ответ, где он запускает код исключения
response1
{
"pk": 1,
"email": "odedeyiopeyemi94@gmail.com",
"fullname": "Opeyemi David Odedeyi",
"profiles": [
{
"id": 1,
"skills": [],
"user": "opeyemi-david-odedeyi-7ug3j0",
"date_of_birth": null,
"bio": null,
"profile_photo": null,
"sex": null,
"type_of_body": null,
"feet": null,
"inches": null,
"lives_in": null,
"updated_on": "2019-12-06T19:31:38.307863+01:00"
}
],
"slug": "opeyemi-david-odedeyi-7ug3j0",
"followers_count": 1,
"following_count": 2,
"am_i_following": "not following"
}
Но изменение кода, когда filter(slug=user.slug)
в функции get_am_i_following
дает мне ответ JSON, но на этот раз возвращает false, когда он должен верните true
{
"pk": 1,
"email": "odedeyiopeyemi94@gmail.com",
"fullname": "Opeyemi David Odedeyi",
"profiles": [
{
"id": 1,
"skills": [],
"user": "opeyemi-david-odedeyi-7ug3j0",
"date_of_birth": null,
"bio": null,
"profile_photo": null,
"sex": null,
"type_of_body": null,
"feet": null,
"inches": null,
"lives_in": null,
"updated_on": "2019-12-06T19:31:38.307863+01:00"
}
],
"slug": "opeyemi-david-odedeyi-7ug3j0",
"followers_count": 1,
"following_count": 2,
"am_i_following": false
}
[ОБНОВЛЕНО]
И просто чтобы быть уверенным, что когда я получаю тех же пользователей, подписчиков, я захожу в систему, что является большей причиной, по которой он должен возвращать True
[
{
"followed_by": "olajumoke-dehinbu-3707yd"
}
]
работает exceptions as e
дал мне
Cannot resolve keyword 'slug' into field. Choices are: blocked_on, followed_by, followed_by_id, followed_on, id, status, unfollowed_on, updated_on, user, user_id