Django Createview保存表单并根据外键

时间:2016-05-21 20:41:36

标签: python django django-forms django-class-based-views

我正在研究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)

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

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

令我困惑的第一件事是template_name中的CreateView变量。我的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')

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

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

我在上面CreateView取得了哪些成就?

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

在这种特殊情况下,我应该做些什么来实现两件事:

  1. 保存数据

  2. 添加一些照片后,将用户重定向到平面详细信息视图。

  3. 其他信息: 我的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 个答案:

答案 0 :(得分:4)

我认为你现在正在混淆两件事。

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

template_name = 'flat_upload_photo.html'

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

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

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

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

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