模型中的 django request.GET

Posted

技术标签:

【中文标题】模型中的 django request.GET【英文标题】:django request.GET in models 【发布时间】:2016-09-10 20:08:57 【问题描述】:

在 Django 中是否可以使用 request.GET 的模型方法? 例如

    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'

)

?

【问题讨论】:

【参考方案1】:

可能,但您必须手动传递request

# inside your views
qs_ = car_object.car_filter(request)

但我认为这样做没有任何意义。

request 有关的所有内容都应该进入视图,这是请求-响应流的地方。

【讨论】:

【参考方案2】:

纯粹从技术上讲,当然可以 - 只要您可以从视图中传递请求对象。您发布的示例代码在语法上不正确,但是,这样的事情在技术上是可行的。您只需确保该方法是类方法,而不是实例方法之一(因为在这种情况下您没有任何实例):

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)
    ...

但是,不要这样做。这是一个坏主意,因为您正在将请求处理逻辑移动到模型中。模型应该只关心数据,处理用户请求是视图的工作。

所以,我建议在视图中包含所有逻辑:

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

如果你需要一些复杂的逻辑,很多观点都会分享,你可以使用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)
    ...

【讨论】:

你不能调用Car.car_filter(request),因为模型方法在行级别工作,它必须用一个对象来调用。表/模型级别的调用是通过 Managers 完成的 @doniyor 你说得对,我答错了。对不起!用@classmethod 修复了这个问题。现在它应该是正确的(虽然我仍然不建议这样做,尤其是传递请求对象 - 管理器是更干净的解决方案) 我想这样做的唯一原因是因为我想为每个 CAR 对象显示相关对象。我想对这些相关对象执行一些过滤器。所以,例如为每个 CAR 相关对象的每个 CAR 执行一些过滤器。我怎样才能在 Django 中做得更好,而不是尝试在模型类中使用带有过滤器的方法? @BlueDog 我建议查看模型管理器示例和链接文档以获取更多详细信息。将实际的过滤逻辑放到自定义模型管理器中,但只传递实际的过滤器值(例如所有者名称或已解析的日期时间) - 而不是包含这些的请求对象。将所有request.GET.get(或类似的)保留在视图代码中 - 这是特定于视图的内容 - 因为将来您可能需要一些必须以不同方式传递或命名参数的视图。【参考方案3】:

实际上你只能在你的视图中处理这些东西

def yourview(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')

否则,您必须将请求对象从您的视图发送到模型函数。

【讨论】:

如果我有一个传递上下文数据的视图,例如'cars' 到我的模板,在模板中我为...循环:对于汽车中的每辆车显示 eachcar.related_object 现在我想通过例如过滤所有相关的对象全局我从另一个视图发布到处理上述上下文数据的视图的日期?目前,我看到过滤这些相关对象的唯一方法是将选择的日期发布到我的模型到相关对象类,因为我看不到在上述视图中使用上下文数据过滤这些相关对象,因为我没有直接引用相关对象那里

以上是关于模型中的 django request.GET的主要内容,如果未能解决你的问题,请参考以下文章

为啥我的“多对多” Django 模型中的 Django 的“add()”方法不采用?

模型形式中的 django auto slug,例如 django admin 中的预填充字段

Django 模型中的有序列表

django模型中的角色

Django中的抽象基类模型与代理模型

模型中的 Django 中的已知错误