Django-filter: UserWarning : X n'est pas compatible avec la génération de schéma : en raison d'AnonymousUser

Créé le 13 août 2018  ·  4Commentaires  ·  Source: carltongibson/django-filter

Je regarde à nouveau les UserWarnings que j'ai essayé d'améliorer dans https://github.com/carltongibson/django-filter/pull/903 :

…/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__)

Ceux-ci se produisent principalement parce qu'un utilisateur anonyme est utilisé, ce qui n'est pas compatible avec la plupart des méthodes get_queryset() de notre vue, qui supposent que l'utilisateur est authentifié (et a certaines méthodes en particulier).

J'utilise drf_yasg ici.

Je me demande s'il existe un moyen d'améliorer cela, par exemple en utilisant un utilisateur authentifié pour cela (ce serait probablement un problème drf-yasg).

Traçage :

../../../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

Commentaire le plus utile

Une solution de contournement possible pourrait être de définir quelque chose comme ceci dans la méthode get_queryset de votre ensemble de vues. Gérer le cas où self.request est None semble faire l'affaire.

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

    return SomeModel.objects.filter(...)

Tous les 4 commentaires

On ne peut pas faire grand chose ici . Toute méthode ayant besoin d'appeler get_queryset() va se heurter à cela. Vous devez essentiellement permettre à cela de gérer le cas anonyme.

Dans tous les cas, le problème est mieux traité dans le cadre de la logique d'introspection de DRF. (Mais il n'y a pas encore de réponse simple non plus.)

Une solution de contournement possible pourrait être de définir quelque chose comme ceci dans la méthode get_queryset de votre ensemble de vues. Gérer le cas où self.request est None semble faire l'affaire.

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

    return SomeModel.objects.filter(...)

Merci @gunthercox votre commentaire m'a vraiment aidé. Cela m'a mis sur la voie de la solution, mais en fin de compte, ce qui a fonctionné pour moi, c'est ceci :

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

J'espère que cela aidera quelqu'un d'autre dans une situation similaire.

Je pense que l'approche suggérée est celle-ci :

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

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

J'ai vu ça dans ce fil : https://github.com/axnsan12/drf-yasg/issues/333

Cette page vous a été utile?
0 / 5 - 0 notes