Django Reste-Cadre: l'Accès de l'élément de détail par slug au lieu de l'ID
Est-il possible d'utiliser un objet de la limace (ou dans tout autre domaine) pour accéder aux détails d'un objet, au lieu de l'aide de l'ID?
Par exemple, si j'ai un objet avec le slug "lorem" et l'ID 1. Par défaut, l'URL est http://localhost:9999/items/1/
. Je veux y accéder via http://localhost:9999/items/lorem/
à la place.
Ajoutant lookup_field
dans le sérialiseur de la Méta-classe ne changera rien à l'généré automatiquement l'URL ni de me permettre d'accéder à l'élément par l'écriture manuelle de la limace au lieu de l'ID dans l'URL.
models.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')
views.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)),
]
Généré JSON:
[
{
"url": "http://localhost:9999/items/1/",
"slug": "lorem",
"title": "Lorem",
"item_url": "http://example.com"
}
]
- Pas le temps pour une réponse complète, mais vous pouvez trouver ce que vous cherchez sur le routeurs docs page pour DRF. Plus précisément, au bas de la section liée pour
SimpleRouter
, regardez l'exemple avecclass MyModelViewSet
. Je pense que c'est en vous permettant de modifier la valeur de la recherche de ce que vous voulez. Peut être un bon point de départ. - Notez que vous êtes en utilisant
DefaultRouter
, pasSimpleRouter
... pas sûr que cette fonctionnalité est dans les deux classes.
Vous devez vous connecter pour publier un commentaire.
Vous devez définir
lookup_field
dans votre sérialiseur:et de votre point de vue:
J'ai obtenu ce résultat:
extra_kwargs = { 'url': {'lookup_field': 'slug'} }
, j'ai reçu le message d'erreur suivant: TypeError: __init__() a obtenu un inattendu argument mot-clé 'lookup_field'. Une fois que je l'ai enlevé, il a bien fonctionné.Dans certains scénarios, vous voudrez peut-être avoir à la fois le "bas niveau"
pk
de la valeur et de la plus sémantiqueslug
. J'aime avoir les deux options personnellement et en définissant lelookup_field
plus tard dans la viewsetas_view()
méthode dans monurls.py
.