Django最有效的方法吗?

时间:2010-05-18 15:46:24

标签: django filter

我开发了一些Django应用程序,就我如何与模型进行交互而言都非常直接。

我现在正在构建一个具有多个不同视图的视图,由于缺少更好的术语,这些视图是“预制”搜索结果页面。这些页面都返回来自同一模型的结果,但它们在不同的列上进行过滤。我们可能在类型上过滤了一个页面,另一个我们可能在类型和大小上进行过滤,而在另一个页面上我们可能只过滤了大小等等...

我在views.py中编写了一个函数,每个页面都使用了这个函数,它需要一个kwargs,并且是搜索的标准。最小值是一个过滤器,但其中一个视图最多有4个。

我只是看看kwargs dict是否包含其中一种过滤器类型,如果有的话我会过滤掉该值的结果(我现在只是写了这段代码,如果有任何错误我道歉,但你应该明白这一点):< / p>

def get_search_object(**kwargs):

  q = Entry.objects.all()

  if kwargs.__contains__('the_key1'):
    q = q.filter(column1=kwargs['the_key1']) 

  if kwargs.__contains__('the_key2'):
    q = q.filter(column2=kwargs['the_key2']) 

  return q.distinct()

现在,根据django文档(http://docs.djangoproject.com/en/dev/topics/db/queries/#id3),这些很好,因为在评估集合之前不会命中数据库,但最近我听说这不是最有效的方法。这样做,而且应该使用Q对象。

我想我正在寻找其他开发者的答案。我的方式目前工作正常,如果我的方式从资源POV完全错误,那么我会尽快改变。

提前致谢

2 个答案:

答案 0 :(得分:3)

从资源方面来说,你很好,但有很多方法可以在风格上进行改进,以避免使用双下划线方法,并使其更灵活,更易于维护。

如果正在使用的kwargs是实际的列名,那么您应该能够非常轻松地简化它,因为您正在做的是解构kwargs并手动重建它,但仅限于此具体的关键词。

def get_search_object(**kwargs):
    entries = Entry.objects.filter(**kwargs)
    return entries.distinct()

主要区别在于它没有强制键是实际列,并且非常需要在那里进行一些异常处理。如果要将其限制为特定字段集,可以指定该列表,然后使用有效条目构建dict。

def get_search_object(**kwargs):
    valid_fields = ['the_key1', 'the_key2']
    filter_dict = {}
    for key in kwargs:
        if key in valid_fields:
            filter_dict[key] = kwargs[key]
    entries = Entry.objects.filter(**filter_dict)
    return entries.distinct()

如果您想要一个更好的解决方案,只需检查该模型上的 有效字段,您就可以(ab)使用_meta

def get_search_object(**kwargs):
    valid_fields = [field.name for field in Entry._meta.fields]
    filter_dict = {}
    for key in kwargs:
        if key in valid_fields:
            filter_dict[key] = kwargs[key]
    entries = Entry.objects.filter(**filter_dict)
    return entries.distinct()

答案 1 :(得分:2)

在这种情况下,从效率的角度来看,您的使用情况很好。如果需要使用OR过滤器而不是AND,则只需要使用Q对象。