Search code examples
djangofiltermodels

django request.GET in models


Is it possible in Django to have models method with request.GET ? e.g.

    class Car(models.Model):
        owner = ForeignKey(Owner)
        car_model = ...
        def car_filter(self, request):
            query = request.GET.get("q")
            if query:
                Car.objects.filter(owner = self.id.order_by('id')
            else:
                Car.objects.filter(owner = me).order_by('id'

)

?


Solution

  • Purely technically speaking, sure, you can - as long as you can pass the request object from the view. The example code you've posted is syntactically incorrect, but, something like this is technically possible. You just have to make sure that the method is class-method, not instance-method one (since you don't have any instances in this case):

    class Car(models.Model):
       ...
       @classmethod
       def get_by_owner(cls, request):
           query = request.GET.get("q")
           if query:
               return cls.objects.filter(owner=query)
           elif request.user.is_authenticated():
               return cls.objects.all()
    
    def your_view(request):
        cars = Car.get_by_owner(request)
        ...
    

    However, DON'T DO THIS. It's a bad idea because you're moving your request processing logic to a model. Models should only care about the data, and user request handling is view's job.

    So, I'd suggest to have all the logic in the views:

    def your_view(request):
        cars = Car.objects.all().order_by("id")
        query = request.GET.get("q")
        if query:
            cars = cars.filter(owner=query)
        ...
    

    If you need some complicated logic, that a lot of views would share, you can use model managers:

    class CarManager(model.Manager):
        def owned(self, username=None):
            queryset = super(CarManager, self).get_query_set()
            if username:
                user = Owner.objects.get(username=username)
                queryset = queryset.filter(owner=user)
            return queryset
    
    class Car(models.Model):
       ...
       objects = CarManager()
    
    ...
    def your_view(request):
        query = request.GET.get("q")
        cars = Car.objects.owned(query)
        ...