2013-10-15 3 views
9

Ciao Sono nuovo sia per Django che per il Django-Rest-Framework. Ho seguito le esercitazioni. Quello che sto cercando di fare (come esercizio di apprendimento) è restituire un oggetto basato su un campo diverso dalla chiave primaria.Ottieni oggetto per campo diverso dalla chiave primaria

  • myserver:8000/videos restituisce un elenco di tutti i video.
  • myserver:8000/videos/1 ritorna il video con chiave primaria di 1

Quello che vorrei fare è:

  • myserver:8000/videos/:videoname restituisce il video in cui videoname = videoname

Ho il seguente video del modello :

class Videos (models.Model): 
    videoID = models.IntegerField(blank=True, null=True) 
    videoName = models.CharField(max_length=20) 
    class Meta: 
     app_label="quickstart" 

Il mio router è configurato come:

video_detail = views.VideoDetailView.as_view({ 
    'get':'list' 
}) 

urlpatterns = patterns('', 
    url(r'^', include(router.urls)), 
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 
    url(r'^videos/(?P<videoName>[^/]+)/$', video_detail) 
) 

E mio punto di vista è definito come:

class VideoDetailView(viewsets.ModelViewSet): 
    serializer_class = VideosSerializer 
    def get_queryset(self): 
     videoName = self.kwargs.get(videoName, None) 
     queryset = super (VideoDetailView,self).get_queryset() 
     if videoName: 
      queryset = queryset.filter(videoName=videoName) 
     return queryset 

Le piste API, ma quando mi ha colpito: myserver:8000/videos/SecondVideo/ (dove "SecondVideo" è il nome del video) Ottengo un errore 404.

Qualsiasi aiuto?

risposta

8

Quindi l'ho capito. Ciò che stava accadendo era il

router.register(r'videos', views.VideosViewSet) 

stava gestendo myserver:8000/videos/1 e quindi il mio un nuovo modello URL url(r'^videos/(?P<videoName>.+)/$', views.VideoDetailView.as_view()) veniva sovrascritti per via raccomandata. Il codice che funziona è:

urls.py 

url(r'^video/(?P<videoName>.+)/$', views.VideoDetailView.as_view()) 

views.py 

class VideoDetailView(generics.ListAPIView): 
    serializer_class = VideosSerializer 

    def get_queryset(self): 
     videoName = self.kwargs['videoName'] 
     return Videos.objects.filter(videoName=videoName) 

Questo documentation page sul filtraggio contro l'URL mi ha aiutato mettere insieme quello che stava succedendo.

10

Provare a impostare l'attributo lookup_field nella classe di visualizzazione. Questo è il campo che verrà utilizzato per cercare una singola istanza di modello. Il valore predefinito è 'pk' ma è possibile cambiarlo in 'videoName'.

class VideoDetailView(viewsets.ModelViewSet): 
    serializer_class = VideosSerializer 
    lookup_field = 'videoName' 
+1

sono andato avanti e ha aggiunto il lookup_field e ho ancora ottenere un 404. Altre idee ? O ragioni per cui questo non funzionerebbe? – rackhamup

+0

Questo ha funzionato per me una volta ottenuto l'URL corretto. Per le persone nuove a Django, ecco l'URL che useresti per cercare un video in cui videoName = 'SecondVideo': http: // localhost: 8000/videos/SecondVideo /? Format = json – Luke

2

Che dire di una soluzione simile a questa:

visualizzazioni.py

class VideoDetailView(generics.RetrieveAPIView): 
    serializer_class = VideosSerializer 
    lookup_field = 'videoName' 

ragionamento: si desidera un detailview, quindi non c'è alcuna necessità di ListView ma RetriveAPIView

se sarà necessario qualche manipolazione furthere basta sovrascrivere get_object metodo come questo:

def get_object(self): 
    obj = super(VideoDetailView, self).get_object() 
    # perform some extra checks on obj, e.g custom permissions 
    return obj 
0

Credito https://www.youtube.com/watch?v=dWZB_F32BDg

Utilizzare lookup_field per definire il campo utilizzato per interrogare la tavola e look_up_kwargs per il campo nel URL

url(r'^videos/(?P<videoName>[^/]+)/$', video_detail)

class VideoDetailView(viewsets.ModelViewSet): 
    serializer_class = VideosSerializer 
    queryset = Videos.objects.all() 
    lookup_field = 'videoName' 
    lookup_url_kwarg = 'videoName'