Как написать запрос ИЛИ, если количество параметров может измениться? - PullRequest
0 голосов
/ 21 октября 2019

Мне нужно сделать фильтр для отображения 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 голосов
/ 21 октября 2019

Вы можете отфильтровать запрос для каждого поля следующим образом:

author = request.POST.get('author', None)
if author:
    searchedObjects = searchedObjects.filter(author=author)
0 голосов
/ 21 октября 2019

Вы можете сделать это следующим образом:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...