Django-filter: UserWarning: X ist nicht kompatibel mit der Schemagenerierung: wegen AnonymousUser

Erstellt am 13. Aug. 2018  ·  4Kommentare  ·  Quelle: carltongibson/django-filter

Ich schaue mir die UserWarnings an, die ich versucht habe, in https://github.com/carltongibson/django-filter/pull/903 zu verbessern:

…/django-filter/django_filters/rest_framework/backends.py:131: UserWarning: <class 'project.app.views.TermsOfServiceViewSet'> is not compatible with schema generation
  "{} is not compatible with schema generation".format(view.__class__)

Dies geschieht hauptsächlich, weil ein AnonymousUser verwendet wird, der mit den meisten get_queryset() Methoden unserer Ansicht nicht kompatibel ist, die davon ausgehen, dass der Benutzer authentifiziert ist (und insbesondere bestimmte Methoden hat).

Ich verwende hier drf_yasg.

Ich frage mich, ob es eine Möglichkeit gibt, dies zu verbessern, zB indem ein authentifizierter Benutzer dafür verwendet wird (wäre dann wahrscheinlich ein DRF-YASG-Problem).

Zurück verfolgen:

../../../Vcs/django-rest-framework/rest_framework/views.py:480: in dispatch
    response = handler(request, *args, **kwargs)
.venv/lib/python3.6/site-packages/drf_yasg/views.py:85: in get
    schema = generator.get_schema(request, self.public)
.venv/lib/python3.6/site-packages/drf_yasg/generators.py:215: in get_schema
    paths, prefix = self.get_paths(endpoints, components, request, public)
.venv/lib/python3.6/site-packages/drf_yasg/generators.py:337: in get_paths
    operation = self.get_operation(view, path, prefix, method, components, request)
.venv/lib/python3.6/site-packages/drf_yasg/generators.py:379: in get_operation
    operation = view_inspector.get_operation(operation_keys)
.venv/lib/python3.6/site-packages/drf_yasg/inspectors/view.py:30: in get_operation
    query = self.get_query_parameters()
.venv/lib/python3.6/site-packages/drf_yasg/inspectors/view.py:293: in get_query_parameters
    natural_parameters = self.get_filter_parameters() + self.get_pagination_parameters()
.venv/lib/python3.6/site-packages/drf_yasg/inspectors/base.py:336: in get_filter_parameters
    fields += self.probe_inspectors(self.filter_inspectors, 'get_filter_parameters', filter_backend()) or []
.venv/lib/python3.6/site-packages/drf_yasg/inspectors/base.py:71: in probe_inspectors
    result = method(obj, **kwargs)
.venv/lib/python3.6/site-packages/drf_yasg/inspectors/query.py:27: in get_filter_parameters
    fields = filter_backend.get_schema_fields(self.view)
../../../Vcs/django-filter/django_filters/rest_framework/backends.py:131: in get_schema_fields
    "{} is not compatible with schema generation".format(view.__class__)
E   UserWarning: <class 'project.app.views.AffiliationViewSet'> is not compatible with schema generation

Hilfreichster Kommentar

Eine mögliche Problemumgehung könnte darin bestehen, so etwas in der Methode get_queryset Ihres Viewsets zu definieren. Der Umgang mit dem Fall, in dem self.request None scheint den Zweck zu erfüllen.

def get_queryset(self):
    if self.request is None:
        return SomeModel.objects.none()

    return SomeModel.objects.filter(...)

Alle 4 Kommentare

Wir können hier nicht viel tun. Jede Methode, die get_queryset() aufrufen muss, wird darauf stoßen. Sie müssen dies grundsätzlich zulassen, um den anonymen Fall zu bearbeiten.

In jedem Fall wird das Problem besser als Teil der Selbstbeobachtungslogik von DRF angegangen. (Aber auch da gibt es noch keine einfache Antwort.)

Eine mögliche Problemumgehung könnte darin bestehen, so etwas in der Methode get_queryset Ihres Viewsets zu definieren. Der Umgang mit dem Fall, in dem self.request None scheint den Zweck zu erfüllen.

def get_queryset(self):
    if self.request is None:
        return SomeModel.objects.none()

    return SomeModel.objects.filter(...)

Danke @gunthercox, dein Kommentar hat mir wirklich geholfen. Es hat mich auf den Weg zur Lösung gebracht, aber letztendlich hat für mich Folgendes funktioniert:

queryset = MyModel.objects.all()

def get_queryset(self):
    if not self.request:
        return MyModel.objects.none()

    if self.request.query_params:
        queryset = self.filter_queryset(self.queryset)
    else:
        queryset = self.queryset

    # ... the rest of the method code ...

    return queryset

Hoffe das hilft jemand anderem in einer ähnlichen Situation.

Ich denke, der vorgeschlagene Ansatz ist dieser:

def get_queryset(self):
    if getattr(self, "swagger_fake_view", False):
        return MyModel.objects.none()

    # ... the rest of the method code ...

Das habe ich in diesem Thread gesehen: https://github.com/axnsan12/drf-yasg/issues/333

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen