Django Return 来自数据库 table 的查询集通过使用字典值过滤

Django Return Queryset from Database table by filtering using Dictionary values

我的目标是使用用户通过搜索表单发送的值 return 书中的行 table。搜索表单包含多个字段 author、ISBN 和 title。

注意:代码中author字段为char,由于外键关系,根据作者姓名转换为ID。

在这段代码中,有一个 get 请求转换为 Dictionary 并转换为允许它从书籍中查询数据 table。

def search(request):

    form = BooksForm()

    if request.method == 'GET':

        # convert get request to dictionary
         book_search = dict(request.GET)
         print("data before cleaning", book_search)

       #get the name from the dictionary get request
         author_name =request.GET['author']
       
        #get the author id from the author table
         author = Author.objects.filter(full_name__contains=author_name).values()

         #get author_id from author queryset
         author_id = author[0]['id']

      #update the dict with the author id to allow search in books models (foreing key)
         book_search['author'] = author_id
         print("data after cleaning",book_search)

         result_set = Book.objects.filter(**book_search)

         print("book search queryset",result_set)

问题: 当我使用字典查询 table 本书时,它 return 是一个空查询集,我希望它是 table 中的 return 本书。 有谁知道我如何使代码工作?

不要允许过滤任意键。这使得视图对 请求伪造 很敏感,例如,一个人可以使用 author__gender 作为键和 F 作为值发出请求,从而可以公开数据你可能想隐藏。

您可以使用像 django-filter [GitHub] 这样的库来确定如何过滤查询集。在这里你可以制作一个看起来像这样的过滤器:

import django_filters

class BookFilter(django_filters.FilterSet):
    author = django_filters.CharFilter(
        <strong>field_name='author__full_name'</strong>,
        lookup_expr='contains'
    )

    class Meta:
        model = Book
        fields = ['isbn']

使用此过滤器,它将仅使用 request.GETauthorisbn 键,从而忽略可能要过滤敏感数据的其他键。

然后您可以将其用于:

def search(request):
    book_filter = <strong>ProductFilter(</strong>request.GET<strong>)</strong>
    print('book search queryset', book_filter<strong>.qs</strong>)
    return render(request, '<em>name-of-template.html</em>', {'book_filter': book_filter})

然后,您可以在模板中使用 {{ book_filter.form }} 基于过滤器的表单,并使用 {% for item in book_filter.qs %} … {% endfor %} 枚举过滤查询集中的项目。