framework example ejemplo create python django django-rest-framework

python - example - django rest framework serializer



Django Rest Framework-No se pudo resolver la URL para una relación con hipervínculo utilizando el nombre de vista "usuario-detalle" (12)

Bottle = serializers.PrimaryKeyRelatedField (read_only = True)

read_only le permite representar el campo sin tener que vincularlo a otra vista del modelo.

Estoy construyendo un proyecto en Django Rest Framework donde los usuarios pueden iniciar sesión para ver su bodega. Mis ModelViewSets funcionaban bien y de repente recibí este error frustrante:

No se pudo resolver la URL para la relación de hipervínculo utilizando el nombre de vista "detalles del usuario". Es posible que no haya incluido el modelo relacionado en su API, o que haya configurado incorrectamente el atributo lookup_field en este campo.

La traza muestra:

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

Tengo un modelo de usuario de correo electrónico personalizado y el modelo de botella en models.py es:

class Bottle(models.Model): wine = models.ForeignKey(Wine, null=False) user = models.ForeignKey(User, null=False, related_name=''bottles'')

Mis serializadores:

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

Mis opiniones:

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

y finalmente la url:

router = routers.DefaultRouter() router.register(r''bottles'', views.BottleViewSet, base_name=''bottles'') urlpatterns = patterns('''', url(r''^'', include(router.urls)), # ...

No tengo una vista detallada del usuario y no veo de dónde podría surgir este problema. ¿Algunas ideas?

Gracias


Debido a que es un HyperlinkedModelSerializer su serializador está tratando de resolver la URL del User relacionado en su Bottle .
Como no tiene la vista detallada del usuario, no puede hacer esto. De ahí la excepción.

  1. ¿No solo el registro del UserViewSet con el enrutador resolvería su problema?
  2. Puede definir el campo de usuario en su BottleSerializer para usar explícitamente el UserSerializer lugar de tratar de resolver la URL. Consulte la documentación del serializador sobre cómo tratar con objetos anidados para eso .

Encontré este error también y lo resolví de la siguiente manera:

La razón es que olvidé darle un "espacio de nombres a" ** - detalle "(nombre_vista, por ejemplo: usuario-detalle) Por lo tanto, Django Rest Framework no pudo encontrar esa vista.

Hay una aplicación en mi proyecto, supongo que mi nombre de proyecto es myproject y el nombre de la aplicación es myapp .

Hay dos archivos urls.py, uno es myproject/urls.py y el otro es myapp/urls.py Le doy a la aplicación un espacio de nombres en myproject/urls.py , como:

url(r'''', include(myapp.urls, namespace="myapp")),

myapp/urls.py enrutadores de marco de trabajo de resto en myapp/urls.py y luego obtuve este error.

Mi solución fue proporcionar url con espacio de nombres explícitamente:

class UserSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="myapp:user-detail") class Meta: model = User fields = (''url'', ''username'')

Y resolvió mi problema.


Este código debería funcionar, también.

class BottleSerializer(serializers.HyperlinkedModelSerializer): user = UserSerializer() class Meta: model = Bottle fields = (''url'', ''wine'', ''user'')


Estuve atrapado en este error por casi 2 horas:

Se configuró incorrectamente en / api_users / users / 1 / No se pudo resolver la URL para una relación de hipervínculo utilizando el nombre de vista "user-detail". Es posible que no haya incluido el modelo relacionado en su API, o que haya configurado incorrectamente el atributo lookup_field en este campo.

Cuando finalmente consigo la solución, pero no entiendo por qué, mi código es:

#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)), ]

pero en mis URL principales, era:

urlpatterns = [ url(r''^admin/'', admin.site.urls), #api users url(r''^api_users/'', include(''usersApi.users_urls'', namespace=''api'')), ]

Así que para finalmente resuelvo el problema borrando el espacio de nombres:

urlpatterns = [ url(r''^admin/'', admin.site.urls), #api users url(r''^api_users/'', include(''usersApi.users_urls'')), ]

Y finalmente resuelvo mi problema, para que cualquiera pueda hacerme saber por qué, mejor.


Me encontré con el mismo error cuando estaba siguiendo la guía de inicio rápido de DRF http://www.django-rest-framework.org/tutorial/quickstart/ y luego intenté buscar / usuarios. He hecho esta configuración muchas veces antes sin problemas.

Mi solución no estaba en el código sino en reemplazar la base de datos.

La diferencia entre esta instalación y las otras anteriores fue cuando creé la base de datos local.

Esta vez corri mi

./manage.py migrate ./manage.py createsuperuser

inmediatamente después de correr

virtualenv venv . venv/bin/activate pip install django pip install djangorestframework

En lugar del orden exacto enumerado en la guía.

Sospeché que algo no fue creado correctamente en el DB. No me importaba mi dev db, así que lo ./manage.py migrate y ejecuté el ./manage.py migrate una vez más, creé un superusuario, navegué a / usuarios y el error desapareció.

Algo fue problemático con el orden de operaciones en el que configuré DRF y la base de datos.

Si está utilizando sqlite y puede probar el cambio a una base de datos nueva, entonces vale la pena intentarlo antes de diseccionar todo su código.


Me encontré con este mismo problema y lo resolví agregando generics.RetrieveAPIView como una clase base a mi conjunto de vistas.


Mismo error, pero diferente razón:

Defino un modelo de usuario personalizado, nada nuevo campo:

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

Esta es mi función de vista:

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

Dado que no proporcioné queryset directamente en UserViewSet , debo establecer base_name cuando registro este conjunto de vistas. Aquí es donde mi mensaje de error causado por el archivo urls.py :

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

Necesita un nombre base_name como el nombre de su modelo: customuser .


Obtuve ese error en DRF 3.7.7 cuando un valor de bala estaba vacío (es igual a '''') en la base de datos.


Otro error desagradable que causa este error es tener el nombre base innecesariamente definido en su urls.py. Por ejemplo:

router.register(r''{pathname}, views.{ViewName}ViewSet, base_name=''pathname'')

Esto causará el error mencionado anteriormente. Obtenga ese nombre base fuera de allí y vuelva a una API que funcione. El siguiente código solucionaría el error. ¡Hurra!

router.register(r''{pathname}, views.{ViewName}ViewSet)

Sin embargo, es probable que no solo haya agregado arbitrariamente el nombre base, sino que lo haya hecho porque definió una definición personalizada get_queryset () para los mandatos de Vista y Django al agregar el nombre base. En este caso, deberá definir explícitamente la ''url'' como un campo de hipervínculo para el serializador en cuestión. Observe que estamos definiendo este HyperlinkedIdentityField ON THE SERIALIZER de la vista que está generando el error. Si mi error fuera "No se pudo resolver la URL para una relación con hipervínculo utilizando el nombre de vista" detalles de estudio ". Es posible que no haya incluido el modelo relacionado en su API, o que haya configurado incorrectamente el atributo lookup_field en este campo". Podría arreglar esto con el siguiente código.

Mi ModelViewSet (el get_queryset personalizado es la razón por la que tuve que agregar el nombre base al router.register () en primer lugar):

class StudyViewSet(viewsets.ModelViewSet): serializer_class = StudySerializer ''''''custom get_queryset'''''' def get_queryset(self): queryset = Study.objects.all() return queryset

Mi registro de enrutador para este ModelViewSet en urls.py:

router.register(r''studies'', views.StudyViewSet, base_name=''studies'')

¡Y AQUÍ ESTÁ DONDE ESTÁ EL DINERO! Entonces podría resolverlo así:

class StudySerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="studies-detail") class Meta: model = Study fields = (''url'', ''name'', ''active'', ''created'', ''time_zone'', ''user'', ''surveys'')

Sí. Debe definir explícitamente este HyperlinkedIdentityField en sí mismo para que funcione. Y debe asegurarse de que el view_name definido en el HyperlinkedIdentityField sea el mismo que definió en el nombre base_name en urls.py con una ''-detail'' agregada después.


Quizás alguien pueda echarle un vistazo a esto: http://www.django-rest-framework.org/api-guide/routers/

Si utiliza el espacio de nombres con serializadores hipervinculados, también deberá asegurarse de que los parámetros de view_name en los serializadores reflejen correctamente el espacio de nombres. Por ejemplo:

urlpatterns = [ url(r''^forgot-password/$'', ForgotPasswordFormView.as_view()), url(r''^api/'', include(router.urls, namespace=''api'')), ]

necesitaría incluir un parámetro como view_name=''api:user-detail'' para los campos del serializador con hipervínculo a la vista de detalles del usuario.

class UserSerializer(serializers.HyperlinkedModelSerializer): url = serializers.HyperlinkedIdentityField(view_name="api:user-detail") class Meta: model = User fields = (''url'', ''username'')


Si está extendiendo las clases GenericViewSet y ListModelMixin , y tiene el mismo error al agregar el campo url en la vista de lista, es porque no está definiendo la vista de detalle. Asegúrese de que está extendiendo la mezcla RetrieveModelMixin :

class UserViewSet (mixins.ListModelMixin, mixins.RetrieveModelMixin, viewsets.GenericViewSet):