Reputation: 469
So I have this system where my Post object has a ManyToMany field and it's called Saves. So like for example on Reddit you can save a post. So I got it working and users can save posts, and it adds them to the ManyToMany field. However, I want to filter out these posts and only show the posts where said user is in the ManyToMany field.
Here is my models.py
class Post(models.Model):
author = models.ForeignKey(User,related_name='posts',on_delete=models.CASCADE)
saves = models.ManyToManyField(User,blank=True,related_name='post_saves')
I have the saves field connected to the User model Django provides.
And here is my views.py
class PostSaveRedirect(RedirectView):
def get_redirect_url(self,*args,**kwargs):
pk = self.kwargs.get("pk")
slug = self.kwargs.get("slug")
obj = get_object_or_404(Post,pk=pk,slug=slug)
url_ = obj.get_absolute_url()
user = self.request.user
if user.is_authenticated:
if user in obj.saves.all():
obj.saves.remove(user)
else:
obj.saves.add(user)
return url_
So this is all working fine, it adds the user to the ManyToMany field, but now I want to know how I can filter out posts and only display ones where the user is in the ManyToMany field.
Here is my saved posts view.
class PostSaveListView(ListView):
model = Post
template_name = 'mainapp/post_saved.html'
paginate_by = 10
queryset = models.Post.objects.all()
def get(self,request):
posts = Post.objects.all()
return render(request, self.template_name)
def get_queryset(self):
return Post.objects.filter().order_by('-published_date')
So with Post.objects.all(), how can I change it so it will filter to my needs? This is a similar queryset for a user post list view I have
I have been Googling and reading up the docs and other articles but have not found anything that has been able to show me how to filter a ManyToMany field. Any help would be much appreciated
Upvotes: 1
Views: 443
Reputation: 945
edit your view like this:
class PostSaveListView(ListView):
model = Post
template_name = 'mainapp/post_saved.html'
paginate_by = 10
def get(self,request):
posts = Post.objects.all()
return render(request, self.template_name)
def get_queryset(self):
object_list = Post.objects.filter(saves__in=[self.request.user]).order_by('-published_date').distinct()
return object_list
Upvotes: 1
Reputation: 180
The easiest and quickest option for you would be to use the filtering option in like this:
def get_queryset(self):
return Post.objects.filter(saves__in=[self.request.user]).order_by('-published_date')
Please notice the list inclusion for the user object, as that option only filters from lists.
You may consider also adding .distinct() call to the filter also to avoid repetition of objects.
Upvotes: 1