DjangoFilterBackend没有使用我的模型(manytomany)

时间:2015-01-31 03:40:57

标签: python django django-rest-framework django-filter

我有一个Django REST项目,其中我使用了来自django-rest-framework-filters github link的DjangoFilterBackend。

这个后端适用于我的一些拥有ForeignKey&然而,ManyToMany关系,它只是对其他一些模型不起作用,总是给我一个AttributeError: 'NoneType' object has no attribute 'verbose_name'。 我的模特:

from django.db import models
from authuser.models import AbstractUser, BaseUserManager
from corporation.models import Corporation


class Organization(AbstractUser):
    company = models.ForeignKey(Corporation, verbose_name='company',
                            related_name='organizations',
                            null=True, on_delete=models.SET_NULL)
    contact_name = models.CharField(max_length=50, verbose_name='contact_name', default='')
    contact_phone = models.CharField(max_length=50, null=True, verbose_name='contact_phone')
    contact_email = models.EmailField(max_length=50,     verbose_name='contact_email', default='')
    about_us = models.TextField(null=True, verbose_name='about_us')
    info_completed = models.BooleanField(default=False,     verbose_name='info_completed')

    objects = BaseUserManager()

    class Meta:
        ordering = ('date_joined',)

我的观点:

class OrganizationDetailView(generics.RetrieveUpdateDestroyAPIView):
    serializer_class = OrganizationSerializer
    queryset = Organization.objects.all()



class OrganizationListCreateView(generics.ListCreateAPIView):
    queryset = Organization.objects.all()
    permission_classes = ()

    def get_serializer_class(self):
        if self.request.method == "POST":
            return CreateOrganizationSerializer
        return OrganizationSerializer

    filter_backends = (
        rest_backends.DjangoFilterBackend,
        filters.SearchFilter,
        filters.OrderingFilter,
    )
    filter_fields = (
        'contact_name',
    )
    filter_class = OrganizationFilter
    search_fields = (
        # 'company',
                     'contact_name',
                     'contact_email', 'contact_phone',
                     'description',
    )
    ordering = ('date_joined')

我的过滤器:

class OrganizationFilter(filters.FilterSet):
    company = filters.RelatedFilter(CorporationFilter, name='company')
    description = filters.AllLookupsFilter(name='description')
    contact_name = filters.AllLookupsFilter(name='contact_name')
    contact_phone = filters.AllLookupsFilter(name='contact_phone')
    contact_email = filters.AllLookupsFilter(name='contact_email')

    class Meta:
        model = Organization
        fields = (
            'company',
            'description', 'contact_name', 'contact_phone',
            'contact_email',
        )

我的序列化器:

class OrganizationSerializer(serializers.ModelSerializer):
    company = serializers.PrimaryKeyRelatedField(queryset=Corporation.objects.all())

    class Meta:
        model = Organization
        fields = ('id', 'company',
                  'contact_name', 'contact_email',
                  'contact_phone', 'info_completed')

CRUD操作没问题。它只是在列出组织时给出了属性错误:

Creating test database for alias 'default'...
E.........
======================================================================
ERROR: test_list_organizations (organization.tests.SimpleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "F:\landi-django\organization\tests.py", line 73, in test_list_organizati
ons
    response = client.get('/organizations?contact_name=Tingtao')
  File "F:\landi-django\env\lib\site-packages\rest_framework\test.py", line 160,
 in get
    response = super(APIClient, self).get(path, data=data, **extra)
  File "F:\landi-django\env\lib\site-packages\rest_framework\test.py", line 86,
in get
    return self.generic('GET', path, **r)
  File "F:\landi-django\env\lib\site-packages\rest_framework\compat.py", line 18
9, in generic
    return self.request(**r)
  File "F:\landi-django\env\lib\site-packages\rest_framework\test.py", line 157,
 in request
    return super(APIClient, self).request(**kwargs)
  File "F:\landi-django\env\lib\site-packages\rest_framework\test.py", line 109,
 in request
    request = super(APIRequestFactory, self).request(**kwargs)
  File "F:\landi-django\env\lib\site-packages\django\test\client.py", line 440,
in request
    six.reraise(*exc_info)
  File "F:\landi-django\env\lib\site-packages\django\core\handlers\base.py", lin
e 111, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "F:\landi-django\env\lib\site-packages\django\views\decorators\csrf.py",
line 57, in wrapped_view
    return view_func(*args, **kwargs)
  File "F:\landi-django\env\lib\site-packages\django\views\generic\base.py", lin
e 69, in view
    return self.dispatch(request, *args, **kwargs)
  File "F:\landi-django\env\lib\site-packages\rest_framework\views.py", line 407
, in dispatch
    response = self.handle_exception(exc)
  File "F:\landi-django\env\lib\site-packages\rest_framework\views.py", line 404
, in dispatch
    response = handler(request, *args, **kwargs)
  File "F:\landi-django\env\lib\site-packages\rest_framework\generics.py", line
311, in get
    return self.list(request, *args, **kwargs)
  File "F:\landi-django\env\lib\site-packages\rest_framework\mixins.py", line 40
, in list
    instance = self.filter_queryset(self.get_queryset())
  File "F:\landi-django\env\lib\site-packages\rest_framework\generics.py", line
144, in filter_queryset
    queryset = backend().filter_queryset(self.request, queryset, self)
  File "F:\landi-django\env\lib\site-packages\rest_framework_filters\backends.py
", line 45, in filter_queryset
    _filter = filter_class(request.QUERY_PARAMS, queryset=queryset)
  File "F:\landi-django\env\lib\site-packages\rest_framework_filters\filterset.p
y", line 61, in __init__
    f = self.filter_for_field(field, filter_.name)
  File "F:\landi-django\env\lib\site-packages\django_filters\filterset.py", line
 400, in filter_for_field
    'label': capfirst(f.verbose_name),
AttributeError: 'NoneType' object has no attribute 'verbose_name'

----------------------------------------------------------------------

我也尝试在django_filters \ filterset.py中评论第400行,但它给了我更多错误。 非常感谢你的帮助!

1 个答案:

答案 0 :(得分:1)

OrganizationFilter上,您定义的description字段可用于过滤至Organization个对象。 description模型上不存在Organization字段,因此django-filter无法根据该字段过滤查询集。你确实看起来有一个about_us字段,我猜这是你打算使用的字段。

您可以通过将OrganizationFilter上的字段重命名为about_us,或将name字段上的description设置为about_us来解决此问题,所以django-filter使用该字段。

class OrganizationFilter(filters.FilterSet):
    company = filters.RelatedFilter(CorporationFilter, name='company')
    about_us = filters.AllLookupsFilter(name='about_us')
    contact_name = filters.AllLookupsFilter(name='contact_name')
    contact_phone = filters.AllLookupsFilter(name='contact_phone')
    contact_email = filters.AllLookupsFilter(name='contact_email')

    class Meta:
        model = Organization
        fields = (
            'company',
            'description', 'contact_name', 'contact_phone',
            'contact_email',
        )

这些更改中的任何一个都应该能够在不引发错误的情况下发挥作用。