2015-08-25 11 views
21

के बजाय स्लग द्वारा आइटम का विवरण एक्सेस करें क्या आईडी का उपयोग करने के बजाय किसी आइटम के विवरण तक पहुंचने के लिए किसी ऑब्जेक्ट के स्लग (या किसी अन्य फ़ील्ड) का उपयोग करना संभव है?Django Rest Framework: ID

उदाहरण के लिए, यदि मेरे पास स्लग "लोरेम" और आईडी 1 वाला कोई आइटम है। डिफ़ॉल्ट रूप से URL http://localhost:9999/items/1/ है। मैं इसके बजाय http://localhost:9999/items/lorem/ के माध्यम से इसे एक्सेस करना चाहता हूं।

सीरियलाइज़र के मेटा क्लास में lookup_field जोड़ना स्वचालित रूप से जेनरेट किए गए यूआरएल को बदलने के लिए कुछ भी नहीं करता और न ही यह मुझे यूआरएल में आईडी के बजाय स्लग लिखकर आइटम तक पहुंचने की इजाजत देता है।

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

जनरेट किया गया JSON:

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

एक पूरा जवाब के लिए समय नहीं है, लेकिन आप के लिए [डीआरएफ के लिए रूटर डॉक्स पेज] पर (http से ढूंढ सकता है: //www.django-rest-framework .org/api-गाइड/रूटर/# simplerouter)। विशेष रूप से, 'SimpleRouter' के लिए लिंक किए गए अनुभाग के नीचे,' क्लास MyModelViewSet' के साथ उदाहरण देखें। मुझे लगता है कि आप लुकअप वैल्यू को जो कुछ भी चाहते हैं उसे बदल सकते हैं। एक अच्छा प्रारंभिक बिंदु हो सकता है। – eykanal

+0

ध्यान दें कि आप 'DefaultRouter' का उपयोग कर रहे हैं, न कि 'SimpleRouter' ... यह सुनिश्चित नहीं है कि यह कार्यक्षमता दोनों वर्गों में कौन सा है। – eykanal

उत्तर

32

आप अपने serializer में lookup_field स्थापित करना चाहिए:

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

और अपने ध्यान में रखते हुए:

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

मैं इस परिणाम मिला:

~ 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/" 
} 
+1

बस यह ध्यान रखना चाहता था कि 'extra_kwargs = {'url' के अतिरिक्त: {'lookup_field': 'slug'}} ', मुझे निम्न त्रुटि मिली: ** TypeError: __init __() को एक अप्रत्याशित कीवर्ड तर्क' lookup_field मिला '**। एक बार मैंने इसे हटा दिया, यह ठीक काम किया। – Michael

+0

वही बात मेरे साथ हुई, धन्यवाद टिप्पणी के लिए धन्यवाद। अन्यथा मैं अधिक समय बर्बाद कर दूंगा। – javed

+1

ऐसा इसलिए हुआ क्योंकि मैं Serializer मेटा क्लास फ़ील्ड tuple में 'url' फ़ील्ड का उपयोग नहीं कर रहा था। 'Url' फ़ील्ड जोड़ने के बाद मैंने इसका उपयोग किया है: extra_kwargs = {'url': {'lookup_field:' slug ''}} – javed

2

कुछ परिदृश्यों में आप "निम्न स्तर" pk मान और अधिक अर्थपूर्ण slug दोनों चाहते हैं। मुझे व्यक्तिगत रूप से दोनों विकल्प रखना पसंद है और lookup_field को बाद में as_view() विधि में urls.py में विधि सेट करके इसे करें।

Note: the following defaults to pk with an optional slug lookup. To combine this with previous answer you would change the lookup_field below to be "pk" instead of "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) 

This could also be in your views.py - my preference is to see it beside the urlpatterns list.