framework example ejemplo create django django-rest-framework

example - Django Rest Framework: Acceda a los detalles de los elementos mediante slug en lugar de ID



django rest framework serializer (2)

¿Es posible usar la barra de un objeto (o cualquier otro campo) para acceder a los detalles de un artículo, en lugar de usar la ID?

Por ejemplo, si tengo un elemento con el slug "lorem" y el ID 1. Por defecto, la URL es http://localhost:9999/items/1/ . Quiero acceder a través de http://localhost:9999/items/lorem/ lugar.

La adición de lookup_field en la clase Meta del serializador no hizo nada para cambiar la URL generada automáticamente ni me permitió acceder al elemento escribiendo manualmente el slug en lugar de la ID en la URL.

modelos.py

class Item(models.Model): slug = models.CharField(max_length=100, unique=True) title = models.CharField(max_length=100, blank=True, default='''') # An arbitrary, user provided, URL item_url = models.URLField(unique=True)

serializers.py

class ClassItemSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Item fields = (''url'', ''slug'', ''title'', ''item_url'')

vistas.py

class ItemViewSet(viewsets.ModelViewSet): queryset = Item.objects.all() serializer_class = ItemSerializer

urls.py

router = DefaultRouter() router.register(r''items'', views.ItemViewSet) urlpatterns = [ url(r''^'', include(router.urls)), ]

JSON generado:

[ { "url": "http://localhost:9999/items/1/", "slug": "lorem", "title": "Lorem", "item_url": "http://example.com" } ]


Debes establecer lookup_field en tu serializador:

class ItemSerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Item fields = (''url'', ''slug'', ''title'', ''item_url'') lookup_field = ''slug'' extra_kwargs = { ''url'': {''lookup_field'': ''slug''} }

y en su opinión:

class ItemViewSet(viewsets.ModelViewSet): queryset = Item.objects.all() serializer_class = ItemSerializer lookup_field = ''slug''

Obtuve este resultado:

~ curl http://127.0.0.1:8000/items/testslug/ | python -mjson.tool { "item_url": "https://example.com/", "slug": "testslug", "title": "Test Title", "url": "http://127.0.0.1:8000/items/testslug/" }


En algunos casos, es posible que desee tener tanto el valor pk "nivel bajo" como la pk más semántica. Me gusta tener ambas opciones personalmente y hacer esto configurando lookup_field más adelante en el método as_view() en mi urls.py

Nota: los siguientes valores predeterminados son pk con una búsqueda opcional de slug . Para combinar esto con la respuesta anterior, cambiaría el campo de lookup_field continuación para que sea "pk" lugar de "slug".

from django.conf.urls import * from rest_framework.urlpatterns import format_suffix_patterns from myobjects import views as myviews # simplify the view definitions by splitting out the options REQDICT = { ''get'': ''retrieve'', ''put'': ''update'', ''patch'': ''partial_update'', ''delete'': ''destroy'' } # define the pk detail view myobject_detail = myviews.MyObjectViewset.as_view(REQDICT) # define the slug detail view myobject_slug_detail = myviews.MyObjectViewset.as_view(REQDICT, lookup_field=''slug'') urlpatterns = [ url(r"^myobjects/(?P<pk>/d*)/$", myobject_detail, name = ''myobject-detail''), url(r"^myobjects/(?P<slug>[-/w]+)/$", myobject_slug_detail, name = ''myobject-slug-detail''), ] urlpatterns = format_suffix_patterns(urlpatterns)

Esto también podría estar en tus views.py - mi preferencia es verlo al lado de la lista de urlpatterns .