custom models.Manager (Django)

Viewed 16

I am a beginner Python programmer. I'm sorry if my question is stupid.

I'm developing a website where user can only have access to their own data. I have implemented data filtering at the views.py:

class LeadListView(LoginRequiredMixin, ListView):
    model = Lead
    template_name = 'crmapp/lead_list.html'

    def get_queryset(self):
        """
        :return:
        """
        return Lead.objects.filter(user=self.request.user)

and this method works. But I have a desire to change models.Manager, so that the last line looks like this:

..
return Lead.user_objects.all()

I have created Custom Manager:

class UserManager(models.Manager):
    def get_queryset(self):
        all_objects = super(self).get_queryset()
        return all_objects.filter(user=self.user.id)

and added it in the model:

class Lead(models.Model):
    '''
    The Class (model for DB) of Leads
    '''
    objects = models.Manager()
    user_objects = UserManager()

    first_name = models.CharField ...

a new Views.py:

class LeadListView(LoginRequiredMixin, ListView):
    model = Lead
    template_name = 'crmapp/lead_list.html'

    def get_queryset(self):
        """
         :return:
        """
        return Lead.user_objects.all(self)

As a result, I get an error that I couldn't get around:

TypeError at /lead_list/ BaseManager.all() takes 1 positional argument but 2 were given

Please help me understand how to implement data filtering for a logged-in user through custom models.Manager

1 Answers

The idea of ModelManager or dataManager is a little bit changed in last Django versions.

in your case you can do:

class UserQuerySet(models.QuerySet):
    
    def get_by(self, request):
        return self.filter(user=request.user)

in model:

class Lead(models.Model):
    '''
    The Class (model for DB) of Leads
    '''
    objects = UserQuerySet.as_manager()
    ... # other staff

in view:

class LeadListView(LoginRequiredMixin, ListView):
    ... # your staff

    def get_queryset(self):
        return super().get_queryset().get_by(self.request)

you don't need template_name in lead list, the view should find it himself. You should simply save lead_list.html in properly named dir.

More here: https://docs.djangoproject.com/en/4.1/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectTemplateResponseMixin.get_template_names

Related