【问题标题】:pass object primary key across templates django跨模板传递对象主键django
【发布时间】:2017-02-08 15:42:31
【问题描述】:

python/django 的新手。我正在使用基于类的视图。我有名为Video 的对象,我希望能够为其创建评级。我有一个DetailView 用于Video,在同一页面上我有一个链接可以将您带到另一个页面来评价DetailView 上的Video(因为我不想弄乱Mixins尚未将所有内容都放在同一页面上)。

如何保留/获取对 DetailView Video 对象的引用,以便在我提交评级时它知道评级是针对 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_view 转到 rating_create 模板时,我希望 Video 的主键与我一起使用。我正在考虑只使用基于函数的视图,类视图让我感到困惑。

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

【问题讨论】:

  • 如果您发现它们更容易理解,那么使用基于函数的视图并没有错。无论您选择基于函数的视图还是基于类的视图,首先要做的是设置您的 url。到目前为止,您对此有何看法?
  • 我在帖子中添加了网址。我尝试了一些不同的方法,在 url 名称中添加主键,这里只是我的尝试之一

标签: python django primary-key


【解决方案1】:

您可以将其作为参数传递给您的 urls.py,类似于

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

video_view.html 模板文件中用当前视频ID 反转它。

然后在你看来:

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)

【讨论】:

  • 所以这是将Video 的主键放在url 中,然后使用kwargs 找到该主键并将该对象返回到视图?然后我需要用视图中的另一种方法将评级保存到get_init 中定义的对象,对吗?
  • 是的,基本上就是这样,您还可以创建自定义 ModelForm 并将视频字段设置为隐藏输入或覆盖 form_valid 方法并使用正确的视频自己保存模型,而不是传递初始值
【解决方案2】:

你的 url 看起来不错,你已经有了 pk。

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)

上述代码的一个缺点是您仅在表单有效时才验证 url 中的 pk。如果您希望验证所有请求的主键,您可以将该代码移到 dispatch 方法中。

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)

【讨论】:

  • 好的,我对您在这里的内容感到有些困惑。 kwargs = super(RatingView, self).get_form_kwargs() 是做什么的?是唯一的kwarg 我不需要pk 吗?我是否需要在某个地方启动实例,我真的不明白那条线在做什么。
  • 请注意,这是基于类的视图的缺点之一 - 如果不了解 form_validget_form_kwargs 等方法的作用,就无法查看视图并理解流程。我已将代码更改为使用form_valid,因为我认为它更简洁。调用return super(RatingView, self).form_valid(form)就是调用CreateViewform_valid方法,这样我们就不用重复代码了。
猜你喜欢
  • 2011-08-17
  • 2017-04-26
  • 2016-09-28
  • 1970-01-01
  • 2018-04-12
  • 1970-01-01
  • 1970-01-01
  • 2021-09-10
  • 1970-01-01
相关资源
最近更新 更多