'ReverseManyToOneDescriptor' object has no attribute 'filter' Django

2.8k views Asked by At

Hi there Im trying to retrieve a specific object from the related model so as to render data to my view specific to that particular object, in my case I have a custom user model and a related model called Seller.

Models

from django.db import models
from django.contrib.auth.models import AbstractUser


# Create your models here.


class CustomUser(AbstractUser):
    is_customer = models.BooleanField(default=False)
    is_seller = models.BooleanField(default=False)


class Seller(models.Model):
    user = models.ForeignKey(CustomUser, on_delete=models.CASCADE, blank=True, null=True)
    store_name = models.CharField(max_length=120)
    address = models.CharField(max_length=180)
    phone = models.IntegerField(blank=True, null=True)
    email = models.CharField( max_length=180, blank=True, null=True )
    

    def __str__(self):
        return self.store_name

View

@method_decorator( seller_required , name='dispatch')
class SellerDashBoardView(ListView):
    model = Seller
    template_name = 'seller_dashboard.html'

    def get_context_data(self, *args, **kwargs):
        user = CustomUser.seller_set.filter(store_name=self.request.user.username)
        context = super(SellerDashBoardView, self).get_context_data( **kwargs)
        context['products'] = Product.objects.filter(seller=user)[:6]
        return context

1

There are 1 answers

0
Fedya Grab On

This is because when you want to filter ManyToOne reverse Relation, you have to make exact the same query as you would've been done with a direct relation:

CustomUser.objects.filter(seller__store_name="Whole Foods") 
# Note that would return a queryset not a single user!
# If you want a CustomUser object you will have to use either get or index the query 

The doc example and explanations are provided here:
https://docs.djangoproject.com/en/3.1/topics/db/examples/many_to_one/

It is also better to use prefetch_related method to tell djano ORM that it does not have to make as many queries as number of related objects, that query should be done in 2 database queries instead of lenght of your related query:

CustomUser.objects.prefetch_related("seller_set").filter(seller__store_name="Whole Foods")

The doc link:
https://docs.djangoproject.com/en/3.1/ref/models/querysets/#prefetch-related

You probably would like to use ...seller_set.filter when you already got a CustomUser object. So if you want to filter its sellers you would use that:

...
user.seller_set.filter(store_name="Whole Foods")

That would provide you the Seller objects queryset filtered by a store name related to a specific user. Basically the same query as this:

Seller.objects.filter(user_pk=user.pk, store_name="Whole Foods")