webentwicklung-frage-antwort-db.com.de

Django Rest Framework - URL für verknüpfte Beziehung konnte nicht mit dem Ansichtsnamen "Benutzerdetails" aufgelöst werden

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

77
bpipat

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.

  1. Würde das Problem nicht nur durch das Registrieren des UserViewSet beim Router gelöst werden?
  2. Sie können das Benutzerfeld in Ihrem 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
75
Carlton Gibson

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.

43
bovenson

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')
16
JackPy

Dieser Code sollte auch funktionieren.

class BottleSerializer(serializers.HyperlinkedModelSerializer):

  user = UserSerializer()

  class Meta:
    model = Bottle
    fields = ('url', 'wine', 'user')
10
caglar

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

9
Colton Hicks

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.

2
Belter

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):
1

Ich habe diesen Fehler in DRF 3.7.7 erhalten, als ein Slug-Wert in der Datenbank leer war (entspricht ''). 

0
mrmuggles

Ich bin auf dieses Problem gestoßen und habe es gelöst, indem ich generics.RetrieveAPIView als Basisklasse zu meinem Viewset hinzugefügt habe.

0
Jace Browning

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

0
hassanzadeh.sd

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.

0
Ben Havilland

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.

0
Cam T

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.

0