Je travaille avec Django pour la première fois et j'essaye de construire une API et je suis quelques tutoriels et exemples et ça marche bien, mais j'exécute le projet maintenant dans une framboise Pi après avoir installé toutes les exigences et le projet échoue avec l'erreur suivante:
Performing system checks...
Unhandled exception in thread started by <function check_errors.<locals>.wrapper at 0xb547adb0>
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.5/site-packages/Django/utils/autoreload.py", line 225, in wrapper
fn(*args, **kwargs)
File "/home/pi/.local/lib/python3.5/site-packages/Django/core/management/commands/runserver.py", line 120, in inner_run
self.check(display_num_errors=True)
File "/home/pi/.local/lib/python3.5/site-packages/Django/core/management/base.py", line 364, in check
include_deployment_checks=include_deployment_checks,
File "/home/pi/.local/lib/python3.5/site-packages/Django/core/management/base.py", line 351, in _run_checks
return checks.run_checks(**kwargs)
File "/home/pi/.local/lib/python3.5/site-packages/Django/core/checks/registry.py", line 73, in run_checks
new_errors = check(app_configs=app_configs)
File "/home/pi/.local/lib/python3.5/site-packages/Django/core/checks/urls.py", line 13, in check_url_config
return check_resolver(resolver)
File "/home/pi/.local/lib/python3.5/site-packages/Django/core/checks/urls.py", line 23, in check_resolver
return check_method()
File "/home/pi/.local/lib/python3.5/site-packages/Django/urls/resolvers.py", line 397, in check
for pattern in self.url_patterns:
File "/home/pi/.local/lib/python3.5/site-packages/Django/utils/functional.py", line 36, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/pi/.local/lib/python3.5/site-packages/Django/urls/resolvers.py", line 536, in url_patterns
patterns = getattr(self.urlconf_module, "urlpatterns", self.urlconf_module)
File "/home/pi/.local/lib/python3.5/site-packages/Django/utils/functional.py", line 36, in __get__
res = instance.__dict__[self.name] = self.func(instance)
File "/home/pi/.local/lib/python3.5/site-packages/Django/urls/resolvers.py", line 529, in urlconf_module
return import_module(self.urlconf_name)
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 673, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/home/pi/Projects/openvpn-monitor/openvpnmonitor/urls.py", line 24, in <module>
url(r'^api/', include('openvpnmonitor.api.urls')),
File "/home/pi/.local/lib/python3.5/site-packages/Django/urls/conf.py", line 34, in include
urlconf_module = import_module(urlconf_module)
File "/usr/lib/python3.5/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 986, in _gcd_import
File "<frozen importlib._bootstrap>", line 969, in _find_and_load
File "<frozen importlib._bootstrap>", line 958, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 673, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 673, in exec_module
File "<frozen importlib._bootstrap>", line 222, in _call_with_frames_removed
File "/home/pi/Projects/openvpn-monitor/openvpnmonitor/api/urls.py", line 16, in <module>
urlpatterns += router.urls
File "/home/pi/.local/lib/python3.5/site-packages/rest_framework/routers.py", line 101, in urls
self._urls = self.get_urls()
File "/home/pi/.local/lib/python3.5/site-packages/rest_framework/routers.py", line 363, in get_urls
urls = super(DefaultRouter, self).get_urls()
File "/home/pi/.local/lib/python3.5/site-packages/rest_framework/routers.py", line 261, in get_urls
routes = self.get_routes(viewset)
File "/home/pi/.local/lib/python3.5/site-packages/rest_framework/routers.py", line 176, in get_routes
extra_actions = viewset.get_extra_actions()
AttributeError: type object 'SessionViewSet' has no attribute 'get_extra_actions'
Mon views.py a le code suivant:
from Django.shortcuts import render
from rest_framework import viewsets
from .models import Session
from .serializers import SessionSerializer
from rest_framework.views import APIView, Response
class SessionViewSet(APIView):
queryset = Session.objects.all()
serializer_class = SessionSerializer
def get(self, request, format=None):
return Response("test")
Je ne sais vraiment pas pourquoi travaille sur mon ordinateur portable mais cela ne fonctionne pas sur mon Raspberry Pi.
Est-ce arrivé à quelqu'un ou quelqu'un sait pourquoi cela se produit?
Merci beaucoup!
Éditer:
Voici mes urls.py
from Django.conf.urls import url
from rest_framework import routers
from openvpnmonitor.api.views import SessionViewSet
router = routers.DefaultRouter()
router.register(r'sessions', SessionViewSet)
urlpatterns = [
url(r'sessions', SessionViewSet.as_view()),
url(r'^docs/', schema_view),
]
urlpatterns += router.urls
Vous l'avez appelé un ensemble de vues, mais cela n'en fait pas un; vous héritez d'APIView qui est une vue générique autonome, pas un ensemble de vues.
Un ensemble de vues doit hériter des ensembles de vues.ViewSet.
Avant Django Rest Framework v3.8 vous pourriez enregistrer un APIView
directement avec un routeur. J'ai fait cela de manière approfondie pour obtenir un Nice assemblé (et versionné) ) API d'auto-documentation pour certains très points de terminaison d'API personnalisés. Si c'était à refaire, j'écrirais probablement le tout de manière plus standard, mais ce n'est pas une option pour tout le monde.
Mais après avoir creusé l'erreur, il s'avère que vous pouvez simplement corriger le problème en donnant au routeur ce qu'il veut et en ajoutant un mannequin get_extra_actions
méthode de classe.
class MyAPIView(APIView):
@classmethod
def get_extra_actions(cls):
return []
#...
Je ne dis pas que c'est bon, mais ça marche pour l'instant.
J'ai récupéré ma documentation et j'ai réussi à passer à DRFv3.8.
Dans views.py, votre ensemble de vues doit hériter de l'ensemble de vues et l'utiliser dans votre code d'essai d'ensemble de vues ci-dessous:
class SessionViewSet(viewsets.ModelViewSet):
queryset = Session.objects.all()
serializer_class = SessionSerializer
def get(self, request, format=None):
return Response("test")
Pour:
djangorestframework==3.11.0
Django==2.2.9
Vous devez remplacer class SessionViewSet(APIView):
par:
from rest_framework import mixins, viewsets
class SessionViewSet(mixins.ListModelMixin,
viewsets.GenericViewSet):
Pour le faire fonctionner. Les internes de DRF ont un peu changé et les autres solutions ne le couperont plus.
Dans mon cas, ce que j'ai fait, c'est que j'ai hérité ma vue de viewsets.Viewset qui est dans le module rest_framework et en plus, j'ai ajouté l'argument basename = your_name dans la fonction router.register () lors de l'enregistrement.
La vue ressemblerait à quelque chose comme:
class SessionViewSet(viewsets.Viewset):
queryset = Session.objects.all()
serializer_class = SessionSerializer
def get(self, request, format=None):
return Response("test")
L'enregistrement du routeur ressemblerait à quelque chose comme:
router.register(r'your_app_name', YourModelNameView, basename='your_app_name')