2013-10-15 2 views
9

Привет Я новичок в Django и Django-Rest-Framework. Я прошел через учебники. То, что я пытаюсь сделать (как упражнение для обучения), возвращает объект, основанный на поле, отличном от первичного ключа.Получить объект по полю, отличному от первичного ключа

  • myserver:8000/videos возвращает список всех видеороликов.
  • myserver:8000/videos/1 возвращает видео с первичным ключом 1

То, что я хотел бы сделать, это:

  • myserver:8000/videos/:videoname возвращает видео, где videoname = videoname

У меня есть следующее Видео модель :

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

Мой маршрутизатор настроен как:

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

И на мой взгляд, определяется как:

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 

АНИ бежит, но когда я попал: myserver:8000/videos/SecondVideo/ (где «SecondVideo» это название видео) Я получаю ошибку 404.

Любая помощь?

ответ

8

Так что я понял. Что происходило было так что мой новый шаблон URL url(r'^videos/(?P<videoName>.+)/$', views.VideoDetailView.as_view()) был быть переопределен зарегистрированным маршрутом

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

Был myserver:8000/videos/1 обработки и. Код, который работает так:

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) 

Это documentation page фильтрацию против URL помог мне собрать воедино то, что происходит.

10

Попробуйте установить атрибут lookup_field на ваш класс вида. Это поле, которое будет использоваться для поиска экземпляра отдельной модели. По умолчанию он равен 'pk', но вы можете изменить его на 'videoName'.

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

Я пошел вперед и добавил lookup_field и я все еще получаю 404. Любые другие идеи ? Или причины, почему это не будет работать? – rackhamup

+0

Это работало для меня, как только я получил URL-адрес. Для людей, новых для Django, вот URL, который вы хотите использовать для поиска видео, где videoName = 'SecondVideo': http: // localhost: 8000/videos/SecondVideo /? Format = json – Luke

2

Как насчет решения такого типа:

просмотров.ру

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

рассуждение: вы хотите DetailView, так что нет никакой необходимости в ListView но RetriveAPIView

если некоторые furthere манипуляция будет необходима только переопределить get_object метод, как это:

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

Кредит https://www.youtube.com/watch?v=dWZB_F32BDg

lookup_field определить поле, используемое для запроса таблицы и look_up_kwargs для поля в 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' 
Смежные вопросы