Ich baue ein Projekt in Django Rest Framework, in dem sich Benutzer anmelden können, um ihren Weinkeller anzusehen .. Meine ModelViewSets funktionierten einwandfrei und plötzlich bekomme ich diesen frustrierenden Fehler:
URL für Hyperlink-Beziehung konnte nicht mit dem Ansichtsnamen "user-detail" aufgelöst werden. Möglicherweise haben Sie das zugehörige Modell nicht in Ihre API aufgenommen oder das
lookup_field
-Attribut für dieses Feld falsch konfiguriert.
Das Traceback zeigt:
[12/Dec/2013 18:35:29] "GET /bottles/ HTTP/1.1" 500 76677
Internal Server Error: /bottles/
Traceback (most recent call last):
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/Django/core/handlers/base.py", line 114, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/viewsets.py", line 78, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/Django/views/decorators/csrf.py", line 57, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/views.py", line 399, in dispatch
response = self.handle_exception(exc)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/views.py", line 396, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/mixins.py", line 96, in list
return Response(serializer.data)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/serializers.py", line 535, in data
self._data = [self.to_native(item) for item in obj]
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/serializers.py", line 325, in to_native
value = field.field_to_native(obj, field_name)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/relations.py", line 153, in field_to_native
return self.to_native(value)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/relations.py", line 452, in to_native
raise Exception(msg % view_name)
Exception: Could not resolve URL for hyperlinked relationship using view
name "user-detail". You may have failed to include the related model in
your API, or incorrectly configured the `lookup_field` attribute on this
field.
Ich habe ein benutzerdefiniertes E-Mail-Benutzermodell und das Flaschenmodell in models.py lautet:
class Bottle(models.Model):
wine = models.ForeignKey(Wine, null=False)
user = models.ForeignKey(User, null=False, related_name='bottles')
Meine Serialisierer:
class BottleSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Bottle
fields = ('url', 'wine', 'user')
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'password', 'is_superuser')
Meine Ansichten:
class BottleViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows bottles to be viewed or edited.
"""
queryset = Bottle.objects.all()
serializer_class = BottleSerializer
class UserViewSet(ListCreateAPIView):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all()
serializer_class = UserSerializer
und schließlich die URL:
router = routers.DefaultRouter()
router.register(r'bottles', views.BottleViewSet, base_name='bottles')
urlpatterns = patterns('',
url(r'^', include(router.urls)),
# ...
Ich habe keine Benutzerdetailansicht und ich kann nicht erkennen, woher dieses Problem kommen könnte. Irgendwelche Ideen?
Vielen Dank
Da es sich um ein HyperlinkedModelSerializer
handelt, versucht Ihr Serialisierer, die URL des zugehörigen User
auf Ihrem Bottle
aufzulösen.
Da Sie keine Benutzerdetailansicht haben, kann dies nicht geschehen. Daher die Ausnahme.
UserViewSet
beim Router gelöst werden?BottleSerializer
definieren, um das UserSerializer
explizit zu verwenden, anstatt zu versuchen, die URL aufzulösen. Weitere Informationen zum Umgang mit geschachtelten Objekten finden Sie in den Dokumenten des serializer . Ich bin auch auf diesen Fehler gestoßen und habe ihn folgendermaßen gelöst:
Der Grund ist, dass ich vergessen habe, "** - detail" (view_name, z. B. user-detail) einen Namespace zu geben. Django Rest Framework konnte diese Ansicht also nicht finden.
Es gibt eine App in meinem Projekt. Angenommen, mein Projektname ist myproject
und der App-Name ist myapp
.
Es gibt zwei urls.py-Dateien, eine ist myproject/urls.py
und die andere ist myapp/urls.py
. Ich gebe der App einen Namespace in myproject/urls.py
, genau wie:
url(r'', include(myapp.urls, namespace="myapp")),
Ich habe die Rest-Framework-Router in myapp/urls.py
registriert und dann diesen Fehler erhalten.
Meine Lösung bestand darin, URL explizit mit Namespace zu versehen:
class UserSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="myapp:user-detail")
class Meta:
model = User
fields = ('url', 'username')
Und es hat mein Problem gelöst.
Vielleicht kann sich jemand dies ansehen: http://www.Django-rest-framework.org/api-guide/routers/
Bei der Verwendung von Namespaces mit Hyperlink-Serialisierern müssen Sie außerdem sicherstellen, dass alle view_name-Parameter in den Serialisierern den Namespace richtig widerspiegeln. Zum Beispiel:
urlpatterns = [
url(r'^forgot-password/$', ForgotPasswordFormView.as_view()),
url(r'^api/', include(router.urls, namespace='api')),
]
sie müssen einen Parameter wie view_name='api:user-detail'
für Serialisierungsfelder angeben, die mit der Benutzerdetailansicht verlinkt sind.
class UserSerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="api:user-detail")
class Meta:
model = User
fields = ('url', 'username')
Dieser Code sollte auch funktionieren.
class BottleSerializer(serializers.HyperlinkedModelSerializer):
user = UserSerializer()
class Meta:
model = Bottle
fields = ('url', 'wine', 'user')
Ein weiterer böser Fehler, der diesen Fehler verursacht, besteht darin, dass der Basisname unnötigerweise in Ihrer URL.py definiert ist. Zum Beispiel:
router.register(r'{pathname}, views.{ViewName}ViewSet, base_name='pathname')
Dies führt zu dem oben angegebenen Fehler. Holen Sie sich diesen base_name und gehen Sie zurück zu einer funktionierenden API. Der folgende Code würde den Fehler beheben. Hurra!
router.register(r'{pathname}, views.{ViewName}ViewSet)
Wahrscheinlich haben Sie den Basisnamen jedoch nicht willkürlich hinzugefügt. Möglicherweise haben Sie dies getan, weil Sie ein benutzerdefiniertes def get_queryset () für die Ansicht definiert haben und Django-Mandate das Hinzufügen des Basisnamens erfordern. In diesem Fall müssen Sie die 'URL' explizit als HyperlinkedIdentityField für den betreffenden Serializer definieren. Beachten Sie, dass wir dieses HyperlinkedIdentityField ON SERIALIZER der Ansicht definieren, die den Fehler auslöst. Wenn der Fehler "URL für verknüpfte Beziehung mit Ansichtsname" Study-Detail "nicht aufgelöst werden konnte. Möglicherweise haben Sie das zugehörige Modell nicht in Ihre API aufgenommen oder das lookup_field
-Attribut für dieses Feld falsch konfiguriert." Ich könnte das mit dem folgenden Code beheben.
Mein ModelViewSet (das benutzerdefinierte get_queryset ist der Grund, weshalb ich zuerst den base_name zum router.register () hinzufügen musste):
class StudyViewSet(viewsets.ModelViewSet):
serializer_class = StudySerializer
'''custom get_queryset'''
def get_queryset(self):
queryset = Study.objects.all()
return queryset
Meine Router-Registrierung für dieses ModelViewSet in urls.py:
router.register(r'studies', views.StudyViewSet, base_name='studies')
Und hier ist das Geld! Dann könnte ich es so lösen:
class StudySerializer(serializers.HyperlinkedModelSerializer):
url = serializers.HyperlinkedIdentityField(view_name="studies-detail")
class Meta:
model = Study
fields = ('url', 'name', 'active', 'created',
'time_zone', 'user', 'surveys')
Ja. Sie müssen dieses HyperlinkedIdentityField für sich selbst explizit definieren, damit es funktioniert. Sie müssen sicherstellen, dass der view_name
, der im HyperlinkedIdentityField definiert ist, derselbe ist, den Sie für base_name
in urls.py definiert haben, gefolgt von einem '-detail'.
Gleicher Fehler, aber anderer Grund:
Ich definiere ein benutzerdefiniertes Benutzermodell, nichts neues Feld:
from Django.contrib.auth.models import (AbstractUser)
class CustomUser(AbstractUser):
"""
custom user, reference below example
https://github.com/jonathanchu/Django-custom-user-example/blob/master/customuser/accounts/models.py
# original User class has all I need
# Just add __str__, not rewrite other field
- id
- username
- password
- email
- is_active
- date_joined
- method, email_user
"""
def __str__(self):
return self.username
Dies ist meine Ansichtsfunktion:
from rest_framework import permissions
from rest_framework import viewsets
from .models import (CustomUser)
class UserViewSet(viewsets.ModelViewSet):
permission_classes = (permissions.AllowAny,)
serializer_class = UserSerializer
def get_queryset(self):
queryset = CustomUser.objects.filter(id=self.request.user.id)
if self.request.user.is_superuser:
queryset = CustomUser.objects.all()
return queryset
Da ich queryset
nicht direkt in UserViewSet
angegeben habe, muss ich base_name
einstellen, wenn ich dieses Viewset registriere. Hier ist meine Fehlermeldung, die durch urls.py
-Datei verursacht wurde:
from myapp.views import (UserViewSet)
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register(r'users', UserViewSet, base_name='customuser') # <--base_name needs to be 'customuser' instead of 'user'
Sie benötigen einen base_name
, der mit Ihrem Modellnamen identisch ist - customuser
.
Wenn Sie die Klassen GenericViewSet und ListModelMixin erweitern und beim Hinzufügen des url - Felds in der Listenansicht denselben Fehler haben, liegt dies daran, dass Sie die Detailansicht nicht definieren. Stellen Sie sicher, dass Sie das RetrieveModelMixin mixin erweitern:
class UserViewSet (mixins.ListModelMixin,
mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
Ich habe diesen Fehler in DRF 3.7.7 erhalten, als ein Slug-Wert in der Datenbank leer war (entspricht '').
Ich bin auf dieses Problem gestoßen und habe es gelöst, indem ich generics.RetrieveAPIView
als Basisklasse zu meinem Viewset hinzugefügt habe.
Wenn Sie die Felder 'id' und 'url' in Ihrem Serializer auslassen, haben Sie kein Problem. Sie können auf die Beiträge zugreifen, indem Sie die im json-Objekt zurückgegebene id verwenden, was die Implementierung Ihres Frontends noch einfacher macht.
Ich hatte das gleiche Problem, ich denke, Sie sollten Ihre überprüfen
get_absolute_url
titel des Methodeneingabewerts des Objektmodells (** kwargs). und benutze den genauen Feldnamen in lookup_field
Ich bin auf die gleiche Fehlermeldung gestoßen, während ich die DRF-Kurzanleitung befolgt habe http://www.Django-rest-framework.org/tutorial/quickstart/ und dann versuchte, nach/users zu suchen. Ich habe dieses Setup schon oft ohne Probleme gemacht.
Meine Lösung bestand nicht im Code, sondern darin, die Datenbank zu ersetzen.
Der Unterschied zwischen dieser Installation und den anderen Versionen war die Erstellung der lokalen Datenbank.
Dieses Mal lief ich meine
./manage.py migrate
./manage.py createsuperuser
gleich nach dem Laufen
virtualenv venv
. venv/bin/activate
pip install Django
pip install djangorestframework
Anstelle der genauen Reihenfolge in der Anleitung.
Ich hatte den Verdacht, dass in der Datenbank etwas nicht richtig erstellt wurde. Ich interessierte mich nicht für mein dev db, also löschte ich es und führte den Befehl ./manage.py migrate
noch einmal aus, erstellte einen Super-Benutzer, schaute nach/users und der Fehler war weg.
Etwas war problematisch mit der Reihenfolge der Operationen, in denen ich DRF und db konfiguriert habe.
Wenn Sie sqlite verwenden und in der Lage sind, den Wechsel zu einer neuen Datenbank zu testen, ist es einen Versuch wert, bevor Sie den gesamten Code analysieren.
Ich war fast 2 Stunden in diesem Fehler stecken:
Nicht ordnungsgemäß konfiguriert bei /api_users/users/1/Kann die URL für eine Hyperlink-Beziehung nicht mit dem Ansichtsnamen "Benutzer-Detail" auflösen. Möglicherweise haben Sie das zugehörige Modell nicht in Ihre API aufgenommen oder das lookup_field
-Attribut für dieses Feld falsch konfiguriert.
Wenn ich endlich die Lösung bekomme, aber nicht verstehe, warum, lautet mein Code:
#models.py
class Users(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50, blank=False, null=False)
email = models.EmailField(null=False, blank=False)
class Meta:
verbose_name = "Usuario"
verbose_name_plural = "Usuarios"
def __str__(self):
return str(self.name)
#serializers.py
class UserSerializer(serializers.HyperlinkedModelSerializer):
class Meta:
model = Users
fields = (
'id',
'url',
'name',
'email',
'description',
'active',
'age',
'some_date',
'timestamp',
)
#views.py
class UserViewSet(viewsets.ModelViewSet):
queryset = Users.objects.all()
serializer_class = UserSerializer
#urls_api.py
router = routers.DefaultRouter()
router.register(r'users',UserViewSet, base_name='users')
urlpatterns = [
url(r'^', include(router.urls)),
]
in meinen Haupt-URLs lautete:
urlpatterns = [
url(r'^admin/', admin.site.urls),
#api users
url(r'^api_users/', include('usersApi.users_urls', namespace='api')),
]
Um das Problem beim Löschen des Namespaces endlich zu beheben, löse ich das Problem:
urlpatterns = [
url(r'^admin/', admin.site.urls),
#api users
url(r'^api_users/', include('usersApi.users_urls')),
]
Und endlich löse ich mein Problem, und jeder kann mir sagen, warum.
Bottle = Serialisierer.PrimaryKeyRelatedField (read_only = True)
mit read_only können Sie das Feld darstellen, ohne es mit einer anderen Ansicht des Modells verknüpfen zu müssen.