当参数数量可能改变时,如何编写OR查询?

时间:2019-10-21 07:58:33

标签: django orm

我需要进行过滤以显示具有以下条件的BookInstances:

  1. BookInstance.public = True
  2. BookInstance.owner != current logged in user
  3. BookInstance.book.title.icontains('some text')
  4. BookInstance.book.description.icontains('some text')
  5. BookInstance.book.authors(id_in=some list of ids)
  6. BookInstance.book.categories(id_in=some list of ids)

条件将合并为: 1 AND 2 AND ( ( 3 OR 4 ) OR 5 OR 6 )

3&4使用相同的文本进行搜索。

视图中的当前脚手架:

searchedObjects = BookInstance.objects.filter(public=True)
if request.user.is_authenticated:
    searchedObjects = searchedObjects.exclude(owner=request.user)
filterObj = dict(request.POST)
for key in filterObj:
    if key == 'bookTitleOrDescription':
        #condition 3 & 4
        bookTitleOrDescription = filterObj[key][0]
    elif key == 'author[]':
        #condition 5
        authorList = filterObj[key]
    elif key == 'category[]':
        #condition 6
        categoryList = filterObj[key]

searchedObjects将具有查询结果。 if, elif是必需的,因为某些参数可能存在也可能不存在。我们必须避免为此编写10种组合。

型号:

class Author(SafeDeleteModel):
    name = models.CharField(max_length=255)

class Category(SafeDeleteModel):
    title = models.CharField(max_length=255)

class Book(SafeDeleteModel):
    title = models.CharField(max_length=255)
    description = models.CharField(max_length=255)
    authors = models.ManyToManyField(Author)
    categories = models.ManyToManyField(Category)

class BookInstance(SafeDeleteModel):
    owner = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    book = models.ForeignKey(Book, on_delete=models.CASCADE)
    public = models.BooleanField(verbose_name='Will show in search ?')
    lendable = models.BooleanField(verbose_name='In good condition ?')

2 个答案:

答案 0 :(得分:1)

您可以像这样过滤每个字段的查询:

author = request.POST.get('author', None)
if author:
    searchedObjects = searchedObjects.filter(author=author)

答案 1 :(得分:0)

您可以通过以下方式进行操作:

filter = Q()

if key == 'category[]':
    filter = filter |  Q(book__category__id__in='some list of ids')

if key == 'author[]':
    filter = filter |  Q(book__authors__id__in='some list of ids')
....
....

data = BookInstance.objects.filter(filter)