Django Createview根据外键的id保存表单并重定向到页面

Posted

技术标签:

【中文标题】Django Createview根据外键的id保存表单并重定向到页面【英文标题】:Django Createview save form and redirect to page according to the id of the foreignkey 【发布时间】:2016-09-18 23:07:35 【问题描述】:

我正在研究 Django 中的 CBV。

我有一个Flat 的页面。我希望用户能够在该页面上添加公寓的一些图片。

公寓的照片存储在模型中,并与UserFlat模型连接。我的模型如下所示:

class Photo(models.Model):
    photo_path = models.ImageField(verbose_name='Фотография')
    photo_user = models.ForeignKey(User, verbose_name='Агент, добавивший фото')
    photo_flat = models.ForeignKey(Flat, verbose_name='Квартира')
    photo_description = models.CharField(verbose_name='Описание', max_length=200, null=True, blank=True)

我的目标:如果用户添加一些图片并按下按钮,图片将被保存到模型中。然后,用户将被重定向到公寓的同一详细视图,并会看到他们添加的图片。

我尝试了不同的选项,但我没有足够的技能来处理这个问题。

首先让我感到困惑的是CreateView 中的template_name 变量。我的 CreateView 看起来像这样:

class PhotoUploadView(CreateView):
    form_class = PhotoUploadModelForm
    template_name = 'photo_upload.html'
    def form_valid(self, form):
        self.instance.photo_user = self.request.user
        self.instance.photo_flat_id = self.kwargs['flat_id']
        form.save()
        return super(PhotoUploadView, self).form_valid(form)

def get_success_url(self):
        return reverse('flatdetail')

如果我不想向用户显示任何不同的页面怎么办?我希望在发布图片后将它们重定向到相同的平面细节视图。由于以下错误,我无法从CreateView 中删除template_name

TemplateResponseMixin requires either a definition of 'template_name' or an implementation of 'get_template_names()'

我在上面的CreateView 中取得了什么成就?

第二个令人困惑的事情:我发布了图片并被重定向到redirect.html,但不是平面细节视图。那很糟。但是我的照片也没有保存。这很糟糕。我尝试将redirect.html 更改为flatdetail.html,但当然,它显示的页面没有其他信息,例如房间、大小、价格等。

在这种特殊情况下我应该怎么做才能实现两件事:

    保存数据

    在添加一些照片后将用户重定向到平面细节视图。

附加信息: 我的urls.py

 url(r'^dev/flat/(?P<flat_id>[0-9]+)/$', views_dev.flat_ajax, name='flatdetail'),
 url(r'^dev/photo-update/(?P<flat_id>[0-9]+)/$', views_dev.PhotoUploadView.as_view(), name='image-update')

我的forms.py

class PhotoUploadModelForm(forms.ModelForm):
    class Meta:
        model = Photo
        fields = ['photo_path']

我在 flatdetail 模板中的表单:

<form action="/dev/photo-update/flat.id/" method="POST">
% csrf_token%
    <input type="file" multiple>
    <button>Send</button>
</form>

【问题讨论】:

由于您使用了我对上一个问题的回答中的代码,因此您应该接受该回答。 您成功了吗,或者您需要更多帮助?如果我的回答是“答案”,你介意接受吗? 【参考方案1】:

我认为您目前混淆了两件事。

您的PhotoUploadView 与您的平面细节视图完全分开。 PhotoUploadView 中的 template_name 变量是加载上传页面时将使用的模板。所以这应该指向您要用于文件上传的任何 HTML。

template_name = 'flat_upload_photo.html'

我注意到您当前的 get_success_url() 函数没有正确缩进。这可能导致该函数在类内无法被识别,因此无法使用。我不确定这是否只是 *** 上的缩进错误,或者也存在于您的实际代码中。我还看到该函数没有正确的参数来进行重定向。如果我们查看您的 urls.py,我们会看到 flatdetail 的 url 需要一个平面 ID。因此,请确保您的 get_success_url() 缩进正确(在类内)并且如下所示:

def get_success_url():
    return reverse('flatdetail', args=(self.kwargs['flat_id'],)

args=(self.kwargs['flat_id'],) 确保我们将带有参数的元组传递给我们正在搜索的 URL。具体是我们要返回的对象的 ID。这是必需的,因为您在 urls.py 中指定的 URL flatdetail URL 需要一个平面 ID。

第三,我认为您的PhotoUploadView 没有实际上传照片的原因与您访问self.instance.photo_user 而不是form.instance.photo_user 的事实有关。此时也不必执行form.save(),因为这将在您调用super() 函数时发生。

我不完全确定您的 form_valid() 中发生了什么。也许如果你能澄清那里出了什么问题(任何错误?)我将能够更好地帮助你。

【讨论】:

感谢您的帮助。当我将函数更改为语句success_url = reverse('flatdetail') 时出现错误The included URLconf 'django_project.urls' does not appear to have any patterns in it. If you see valid patterns in the file then the issue is probably caused by a circular import. 当我尝试加载公寓页面时发生错误。我将函数更改为reverse_lazy ,现在我在尝试发布图片时遇到了同样的错误 reverse_lazy 错误实际上已经消失,但我没有重定向回公寓的页面。 Django 渲染redirect.html 这是一个空页面并显示它。照片也没有保存。我看不到任何错误 @mailman_73 我已经更新了我的答案。我实际上错了使用success_url 变量。您是否使用正确的 form.instance.photo_user 值更新了 form_valid() 中的值? 再次感谢您的帮助。但它仍然只是返回空白redirect.html,而不是重定向到同一页面。发生这种情况是因为我的表格数据无效吗?而不是 return flatdetail view django 返回 CBV 的模板?或者问题出在&lt;form action="/dev/photo-update/flat.id/" method="POST"&gt;?表单存储在flatdetail template,没有个人模板/页面 @mailman_73 从技术上讲,您不需要将表单 action 设置为任何内容(如果您将其留空,则默认为同一页面,这就是您想要的)。如果您将print "Form valid!" 添加到form_valid() 函数中,您应该会在您发布正确数据时在服务器日志中看到此输出。如果您没有看到此输出,则表示您发布数据时出现问题。这可能是几件事,可能需要提出一个新问题。

以上是关于Django Createview根据外键的id保存表单并重定向到页面的主要内容,如果未能解决你的问题,请参考以下文章

根据同一模型中的另一个外键动态限制 Django 模型中外键的​​选择

Django ORM - 我可以使用 ID 以外的其他列创建具有外键的新对象吗?

Django CreateView get_initial 外键

Django - 如何在相关模型上为外键创建多个选择(在 CreateView 上)?

Django 啥时候查找外键的主键?

如何在DJANGO里,向有外键的DB里插入数据