通过 django API 按模型过滤的问题

Issue with filtering via django API by models

这是我的问题,我有下一个申请:

class Product(models.Model):
    CHOICES = ('VM', 'BM')
    name = models.CharField(max_length=64, unique=True)
    types = models.CharField(choices=CHOICES, max_length=16,
            default=CHOICES[0])

from products import Product
class Invent(models.Model):
    item = models.ForeignKey(Product, to_field='name', default=1)

我也为他们创造了API。它工作正常,但我需要按模型创建过滤器,但不知道如何。 例如,我需要在 API 中获取所有项目列表,但仅在 Product 应用程序中它是 "VM"。我该怎么做?

如果需要的话有我的一些例子,但它不是过滤: 例如:

class ShellMessageFilterVM(django_filters.FilterSet):

   types = Product.objects.filter(types="VM")
   item =  django_filters.ModelChoiceFilter(queryset=Invent.objects.filter(item=types))

   class Meta:
        model = Invent
        fields = ['item']

class InventoryAvailableVMList(ListAPIView):
    serializer_class = InventSerializer
    queryset = Invent.objects.all()
    filter_class = ShellMessageFilterVM

并收到错误:

(1242, 'Subquery returns more than 1 row')

完整追溯:

Environment:


Request Method: GET

Django Version: 1.9 Python Version: 2.7.5 Installed Applications: ['product.apps.ProductConfig',   'invent.apps.InventConfig',,  'django.contrib.admin',  'django.contrib.auth',  'django.contrib.contenttypes',  'django.contrib.sessions',  'django.contrib.messages',  'django.contrib.staticfiles',  'rest_framework',  'rest_framework.authtoken'] Installed Middleware: ['django.middleware.security.SecurityMiddleware',  'django.contrib.sessions.middleware.SessionMiddleware',  'django.middleware.common.CommonMiddleware',  'django.middleware.csrf.CsrfViewMiddleware',  'django.contrib.auth.middleware.AuthenticationMiddleware',  'django.contrib.auth.middleware.SessionAuthenticationMiddleware',  'django.contrib.messages.middleware.MessageMiddleware',  'django.middleware.clickjacking.XFrameOptionsMiddleware']


Template error: In template /usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework/templates/rest_framework/filters/django_filter.html, error at line 4    1242   1 : {% load i18n %}    2 : <h2>{% trans "Field filters" %}</h2>    3 : <form class="form" action="" method="get">    4 :      {{ filter.form.as_p }}     5 :     <button type="submit" class="btn btn-primary">{% trans "Submit" %}</button>    6 : </form>    7 : 

Traceback:

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  174.                     response = self.process_exception_by_middleware(e, request)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/core/handlers/base.py" in get_response
  172.                     response = response.render()

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/response.py" in render
  160.             self.content = self.rendered_content

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework/response.py" in rendered_content
  71.         ret = renderer.render(self.data, media_type, context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework/renderers.py" in render
  675.         context = self.get_context(data, accepted_media_type, renderer_context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework/renderers.py" in get_context
  654.             'filter_form': self.get_filter_form(data, view, request),

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework/renderers.py" in get_filter_form
  596.                 html = backend().to_html(request, queryset, view)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework_filters/backends.py" in to_html
  35.         return compat.template_render(template, context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/rest_framework/compat.py" in template_render
  232.         return template.render(context, request=request)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/backends/django.py" in render
  95.             return self.template.render(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in render
  206.                     return self._render(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in _render
  197.         return self.nodelist.render(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in render
  988.                 bit = node.render_annotated(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in render_annotated
  955.             return self.render(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in render
  1039.             output = self.filter_expression.resolve(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in resolve
  705.                 obj = self.var.resolve(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in resolve
  846.             value = self._resolve_lookup(context)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/template/base.py" in _resolve_lookup
  909.                             current = current()

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/forms.py" in as_p
  281.             errors_on_separate_row=True)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/forms.py" in _html_output
  218.                     'field': six.text_type(bf),

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/utils/html.py" in <lambda>
  381.         klass.__unicode__ = lambda self: mark_safe(klass_unicode(self))

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/boundfield.py" in __str__
  43.         return self.as_widget()

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/boundfield.py" in as_widget
  101.         return force_text(widget.render(name, self.value(), attrs=attrs))

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/widgets.py" in render
  528.         options = self.render_options(choices, [value])

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/widgets.py" in render_options
  554.         for option_value, option_label in chain(self.choices, choices):

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/forms/models.py" in __iter__
  1109.         for obj in queryset:

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/models/query.py" in __iter__
  52.         results = compiler.execute_sql()

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/models/sql/compiler.py" in execute_sql
  852.             cursor.execute(sql, params)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  79.             return super(CursorDebugWrapper, self).execute(sql, params)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/utils.py" in __exit__
  95.                 six.reraise(dj_exc_type, dj_exc_value, traceback)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/backends/utils.py" in execute
  64.                 return self.cursor.execute(sql, params)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/django/db/backends/mysql/base.py" in execute
  112.             return self.cursor.execute(query, args)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/MySQLdb/cursors.py" in execute
  205.             self.errorhandler(self, exc, value)

File "/usr/local/hosting/hosting/lib/python2.7/site-packages/MySQLdb/connections.py" in defaulterrorhandler
  36.     raise errorclass, errorvalue

Exception Type: OperationalError at /fulfillment/api/inventory_available/vm/ Exception Value: (1242, 'Subquery returns more than 1 row')

我的serializers.py

class InventSerializer(serializers.ModelSerializer):
    item = serializers.SlugRelatedField(queryset=Product.objects.all(),
                                           slug_field='name')

    class Meta:
        model = Invent
        fields = ('id', 'item')

你应该看看documentation about FilterSet

如果您想按 item.types 过滤,您的 ShellMessageFilterVM 应该如下所示:

class ShellMessageFilterVM(filters.FilterSet):
    class Meta:
        model = Item
        fields = ['item__types']

然后您可以使用 ?item__types=VM

进行过滤