Пользователи вместо id , Django(wagtail), Vue
Я хочу сделать класс, который возвращает usename всех пользователей, которым понравился пост. Пользователи будут отправлены в Vue. В настоящее время код возвращает в Vue consol log - 0: {likex: 'ideas.IdeaPage.None'}
models.py
class IdeaPage(Page):
intro = models.CharField(max_length=250)
body = RichTextField()
tags = models.CharField(max_length=100, null=True, blank=True)
likex = models.ManyToManyField(User, related_name="likex", blank=True)
serializer.py
class LikeSerializer(serializers.ModelSerializer):
likex = serializers.CharField()
class Meta:
model = IdeaPage
fields = ["likex"]
views.py
@authentication_classes([authentication.TokenAuthentication])
@permission_classes([permissions.IsAuthenticated])
class Like(APIView):
def get(self, request, id, format=None):
ideasl = IdeaPage.objects.get(id=id)
likepost = IdeaPage.objects.get(id=id)
likepostZ = likepost.likex.all()
if request.user in likepost.likex.get_queryset():
likepost.likex.remove(request.user)
else:
likepost.likex.add(request.user)
serializer = LikeSerializer(likepostZ, many=True)
return Response(serializer.data)
почему код возвращает likex: 'ideas.IdeaPage.None'?
Использование CharField для количества лайков является "странным". Вы можете просто использовать IntegerField и аннотировать объект соответствующим образом, например:
class LikeSerializer(serializers.ModelSerializer):
likex = serializers.IntegerField(source='num_likes')
class Meta:
model = IdeaPage
fields = ['likex']
и в представлении мы аннотируем объект количеством лайков:
from django.db.models import Count
from django.shorcuts import get_object_or_404
@authentication_classes([authentication.TokenAuthentication])
@permission_classes([permissions.IsAuthenticated])
class Like(APIView):
def get(self, request, id, format=None):
qs = IdeaPage.objects.annotate(
num_likes=Count('likex')
)
like_post = get_object_or_404(qs, pk=id)
if request.user in like_post.likex.all():
like_post.likex.remove(request.user)
like_post.num_likes += 1
else:
likepost.likex.add(request.user)
like_post.num_likes -= 1
serializer = LikeSerializer(like_post)
return Response(serializer.data)
Но, вы должны не любить или не любить элемент с помощью GET-запроса. Запрос GET следует считать безопасным. Действительно, в разделе о безопасных методах спецификации HTTP говорится:
В частности, было установлено, что методы GET и HEAD НЕ ДОЛЖНЫ иметь значение выполнения какого-либо действия, кроме извлечения. Эти методы должны считаться "безопасными". Это позволяет агентам пользователя представлять другие методы, такие как POST, PUT и DELETE, особым образом, чтобы пользователь знал о том, что запрашивается возможно небезопасное действие.
Таким образом, лайк элемента должен быть реализован с помощью POST-запроса. Вы можете реализовать GET-запрос для обмена количеством лайков, и таким образом перенести логику изменения количества лайков в метод post(…).
Для списка членов, с которыми вы можете работать с PrimaryKeyRelatedField [DRF-doc]:
class LikeSerializer(serializers.ModelSerializer):
likex = serializers.PrimaryKeyRelatedField(many=True)
class Meta:
model = IdeaPage
fields = ['likex']
или для имен пользователей с SlugRelatedField [DRF-doc]:
class LikeSerializer(serializers.ModelSerializer):
likex = serializers.SlugRelatedField(
slug_field='username',
queryset=User.objects.all(),
many=True
)
class Meta:
model = IdeaPage
fields = ['likex']
тогда представление определяется как:
from django.db.models import Count
from django.shorcuts import get_object_or_404
@authentication_classes([authentication.TokenAuthentication])
@permission_classes([permissions.IsAuthenticated])
class Like(APIView):
def get(self, request, id, format=None):
like_post = get_object_or_404(IdeaPage, pk=id)
serializer = LikeSerializer(like_post)
return Response(serializer.data)
def post(self, request, id, format=None):
like_post = get_object_or_404(IdeaPage, pk=id)
if request.user in like_post.likex.all():
like_post.likex.remove(request.user)
else:
likepost.likex.add(request.user)
serializer = LikeSerializer(like_post)
return Response(serializer.data)