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
的页面。我希望用户能够在该页面上添加公寓的一些图片。
公寓的照片存储在模型中,并与User
和Flat
模型连接。我的模型如下所示:
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 的模板?或者问题出在<form action="/dev/photo-update/flat.id/" method="POST">
?表单存储在flatdetail template
,没有个人模板/页面
@mailman_73 从技术上讲,您不需要将表单 action
设置为任何内容(如果您将其留空,则默认为同一页面,这就是您想要的)。如果您将print "Form valid!"
添加到form_valid()
函数中,您应该会在您发布正确数据时在服务器日志中看到此输出。如果您没有看到此输出,则表示您发布数据时出现问题。这可能是几件事,可能需要提出一个新问题。以上是关于Django Createview根据外键的id保存表单并重定向到页面的主要内容,如果未能解决你的问题,请参考以下文章
根据同一模型中的另一个外键动态限制 Django 模型中外键的选择
Django ORM - 我可以使用 ID 以外的其他列创建具有外键的新对象吗?
Django CreateView get_initial 外键