I load "endless scroll" feed via AJAX and pagination. Before passing objects to JS code, I need to add property(or is it called attribute ?) to every object, which contains boolean, whether it was liked by current user or not. I thought it might work but something is wrong, because everything is getting undefined in frontend. How do I implement what I want in the right way? It's important to create property for every object, because later it's very practical just to fetch it the loop same as other data.
def loadmore(request,page_number):
answers_to_questions_objects = Question.objects.filter(whom=request.user.profile).filter(answered=True).order_by('-answered_date')
paginator = Paginator(answers_to_questions_objects,10)
current_page = (paginator.page(page_number))
for item in current_page:
if request.user.profile in item.who_liked.all():
item.liked = True
else:
item.liked = False
print(current_page.liked)
answers = serializers.serialize('json', current_page)
data = {
'answers': answers,
}
return Response(data)
serializers.serialize
will only include the model fields. It won't include the attribute you set on model objects. Instead make a dict and add liked
as a key into it.
import json
def loadmore(request,page_number):
# I added prefetch, so it will avoid making queries inside your loop.
answers_to_questions_objects = Question.objects.filter(whom=request.user.profile).filter(answered=True).order_by('-answered_date').prefetch_related('who_liked')
paginator = Paginator(answers_to_questions_objects,10)
current_page = (paginator.page(page_number))
# I don't know why Question model objects are called answers.
answers = []
for item in current_page:
item_dict = { 'whom': item.whom.name,
'id': item.id,
# Add the other required fields.
}
if request.user.profile in item.who_liked.all():
item_dict['liked'] = True
else:
item_dict['liked'] = False
answers.append(item_dict)
data = {
'answers': json.dumps(answers),
}
return Response(data)
Update:
You should checkout django-rest-framework
if you have to implement a lot of views like this. The serializer api and generic views that comes with it makes life a lot easier.
I need to add property(or is it called attribute ?) to every object, which contains boolean, whether it was liked by current user or not.
That fits better as a method on the model itself:
class Question(models.Model):
""" A question on the site. """
# …
def liked_by_user(self, user):
""" Is this question liked by `user`? """
profile_users = {p.user for p in self.who_liked}
liked = (user in profile_users)
return liked
That way, the view has access to Question.liked_by_user(current_user)
for any question instance.
You don't show a minimal complete verifiable example of your model definitions here, so I'll guess at a complete example:
# models.py
from django.contrib.auth.models import User
from django.db import models
class UserProfile(models.Model):
""" The profile details for a user. """
user = models.ForeignKey(User)
class Question(models.Model):
""" A question on the site. """
answered_date = models.DateField()
def liked_by_user(self, user):
""" Is this question liked by `user`? """
profile_users = {p.user for p in self.who_liked}
liked = (user in profile_users)
return liked
class Like(models.Model):
""" A flag that a user likes a question. """
question = models.ForeignKey(Question, related_name='who_liked')
user_profile = models.ForeignKey(UserProfile)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.