2017-02-08 5 views
1

новый для python/django. Я использую представления на основе классов. У меня есть объекты с именем Video, которые я хочу, чтобы иметь возможность создавать рейтинги. У меня есть DetailView для Video, и на этой же странице у меня есть ссылка, которая приведет вас на другую страницу, чтобы оценить Video, что было на DetailView (потому что я не хотел связываться с Mixins еще, чтобы все это на одном и том же страница).передать объект первичный ключ через шаблоны django

Как я могу сохранить/получить ссылку на DetailViewVideo объект так, когда я представляю рейтинг он знает, что рейтинг для Video объекта, который был на DetailView?

models.py

class Video(models.Model): 
    title = models.CharField(max_length=100, default="Community Video ") 

class Rating(models.Model): 
    rate_choice = ((1, '1'), (2, '2'), (3, '3'), (4, '4'), (5, '5')) 
    rate_value = models.IntegerField(default=5, choices=rate_choice) 
    video = models.ForeignKey('Video', related_name='video', null=True, default=1) 

views.py

class VideoView(DetailView): 
    model = Video 
    template_name = 'video_view.html' 


class RatingView(CreateView): 
    model = Rating 
    template_name = 'rating_create.html' 
    fields = ['rate_value', 'video'] 

В основном я хочу первичный ключ Video пойти со мной, когда я иду из шаблона в video_view к rating_create. Я думаю о том, что просто использую функции, основанные на представлениях, представления класса меня путают.

urls.py:

urlpatterns = [ 
    url(r'^upload', UploadVideo.as_view(), name='upload'), 
    url(r'^(?P<pk>[0-9]+)/$', VideoView.as_view(), name='videoview'), 
    url(r'^(?P<pk>[0-9]+)/ratings', RatingView.as_view(success_url='success_yea'), name='rating_view'), 
    url(r'^success', upload, name='success_yea') 
] 
+0

Нет ничего плохого в использовании функций, основанных на представлении, если вы найдете их более понятными. Независимо от того, выбираете ли вы функции, основанные на представлениях или представления на основе классов, первое, что нужно сделать, это настроить свои URL-адреса. Что у вас есть для этого до сих пор? – Alasdair

+0

Я добавил URL-адреса на свой пост. Я пробовал несколько разных вещей с добавлением первичного ключа в имени URL-адреса, то, что у меня есть, является лишь одним из моих attemps – ratrace123

ответ

0

Вы можете передать это как параметры на вашем urls.py, что-то вроде

url(r'^(?P<pk>[0-9]+)/ratings', RatingView.as_view(), 

В файле video_view.html шаблона реверс с текущим видео ид.

И тогда, на ваш взгляд:

class RatingView(CreateView): 
    model = Rating 
    template_name = 'rating_create.html' 
    fields = ['rate_value'] 
    success_url = reverse_lazy('success_yea') 

    def form_valid(self, form): 
     form.instance.video = get_object_or_404(Video, id=self.kwargs.get('pk')) 
     return super(RatingView, self).form_valid(form) 
+0

, поэтому он помещает первичный ключ «Видео» в URL-адрес, а затем использует 'kwargs' для поиска этот первичный ключ и вернуть этот объект в представление? Затем мне нужно сохранить рейтинг до объекта, который был определен в 'get_init', с другим методом в правом представлении? – ratrace123

+0

Да, это в основном идея, вы также можете создать пользовательский ModelForm и сделать видеополе скрытым вводом или переопределить метод form_valid и сохранить модель самостоятельно с правильным видео, а не передавать начальные – Mounir

0

Ваш URL выглядит хорошо, у вас уже есть рк там.

url(r'^(?P<pk>[0-9]+)/ratings', RatingView.as_view(), name='rating_view'), 

По вашему мнению, вы должны удалить video из списка полей, потому что вы не хотите, чтобы быть доступным для редактирования.

Затем вы можете переопределить form_valid и установить video на экземпляр формы.

from django.shortcuts import get_object_or_404  
from django.urls import reverse 

class RatingView(CreateView): 
    model = Rating 
    template_name = 'rating_create.html' 
    fields = ['rate_value'] 
    # I recommend moving this here, to avoid splitting config between the view and the urls. 
    # You need reverse_lazy to turn the pattern name into the url 
    success_url = reverse_lazy('success_yea') 

    def form_valid(self, form): 
     # Fetch video from the db to check it exists 
     video = get_object_or_404(Video, pk=self.kwargs['pk']) 
     form.instance.video = video 
     return super(RatingView, self).form_valid(form) 

Недостаток вышеуказанного кода заключается в том, что вы подтверждаете только pk в URL-адресе, когда форма действительна. Если вы предпочитаете проверять первичный ключ для всех запросов, вы можете переместить этот код в метод отправки.

class RatingView(CreateView): 
    model = Rating 
    template_name = 'rating_create.html' 
    fields = ['rate_value'] 
    success_url = reverse_lazy('success_yea') 

    def dispatch(self, request, *args, **kwargs): 
     # Fetch video from the db to check it exists 
     self.video = get_object_or_404(Video, pk=self.kwargs['pk']) 
     return super(RatingView, self).dispatch(request, *args, **kwargs) 

    def form_valid(self, form): 
     form.instance.video = self.video 
     return super(RatingView, self).form_valid(form) 
+0

ok Я немного смущен тем, что у вас здесь , Что делает 'kwargs = super (RatingView, self) .get_form_kwargs()' do? Является ли только 'kwarg' мне не' pk'? И мне нужно инициировать экземпляр где-то, я действительно не понимаю, что делает эта строка. – ratrace123

+0

Обратите внимание, что это один из недостатков классических представлений - вы не можете смотреть на представление и понимать поток, не понимая, что делают методы типа form_valid и get_form_kwargs. Я изменил код, чтобы использовать 'form_valid' вместо этого, потому что я думаю, что он немного чище. Вызов 'return super (RatingView, self) .form_valid (form)' вызывает метод 'form_valid'' CreateView', поэтому нам не нужно дублировать код. – Alasdair

Смежные вопросы