代码之家  ›  专栏  ›  技术社区  ›  googletorp

如何用get_object_或_404排除结果?

  •  13
  • googletorp  · 技术社区  · 16 年前

    在Django中,可以使用exclude创建类似于 not equal . 一个例子是。

    Model.objects.exclude(status='deleted')
    

    现在这很有效,排除非常灵活。因为我有点懒惰,所以我想在使用 get_object_or_404 ,但我找不到这样做的方法,因为您不能在上使用exclude 获取对象或404 .

    我要做的就是这样:

    model = get_object_or_404(pk=id, status__exclude='deleted')
    

    但不幸的是,这不起作用,因为没有排除查询过滤器或类似的过滤器。到目前为止,我想到的最好的办法是做这样的事情:

    object = get_object_or_404(pk=id)
    if object.status == 'deleted':
        return HttpResponseNotfound('text')
    

    做那样的事情,真的会破坏使用的意义 获取对象或404 因为它不再是一个方便的一行程序。

    或者我可以这样做:

    object = get_object_or_404(pk=id, status__in=['list', 'of', 'items'])
    

    但这不是很容易维护的,因为我需要保持列表的最新状态。

    我想知道我是不是错过了在姜戈使用的一些技巧或功能 获取对象或404 为了得到想要的结果?

    4 回复  |  直到 8 年前
        1
  •  16
  •   interjay    16 年前

    使用 django.db.models.Q :

    from django.db.models import Q
    
    model = get_object_or_404(MyModel, ~Q(status='deleted'), pk=id)
    

    q对象不允许 ~ 操作员)和或 | 操作员)以及。

    注意q对象必须在 pk=id ,因为关键字参数在python中必须排在最后。

        2
  •  6
  •   Jamneck    9 年前

    最常见的用例是传递模型。但是,您也可以传递一个查询集实例:

    queryset = Model.objects.exclude(status='deleted')
    get_object_or_404(queryset, pk=1)
    

    Django文档示例: https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#id2

        3
  •  1
  •   Corey McMahon    10 年前

    有另一种方法代替使用q对象。而不是将模型传递给 get_object_or_404 只需将queryset传递给函数:

    model = get_object_or_404(MyModel.objects.filter(pk=id).exclude(status='deleted'))

    然而,这一点的一个副作用是,它将提高 MultipleObjectsReturned 如果查询集返回多个结果,则出现异常。

        4
  •  0
  •   Tim Tisdall    8 年前

    get_object_or_404 利用 get_queryset 对象管理器的方法。如果您覆盖 GET-SqQueSeSET 方法只返回未“删除”的项,然后 获取对象或404 将自动按您的需要进行操作。但是,重写 GET-SqQueSeSET 像这样,其他地方可能会出现问题(可能在管理页面中),但您可以为需要访问软删除项时添加备用管理器。

    from django.db import models
    
    class ModelManger(models.Manger):
        def get_queryset(self):
            return super(ModelManger, self).get_queryset().exclude(status='deleted')
    
    class Model(models.Model):
        # ... model properties here ...
    
        objects = ModelManager()
        all_objects = models.Manager()
    

    因此,如果您只需要未删除的项目,您可以这样做 get_object_or_404(Models, id=id) 但是如果你需要所有的东西,你可以做 get_object_or_404(Models.all_objects, id=id) .