Django:编辑现有对象,但保存时新增

时间:2015-03-31 09:44:56

标签: django django-forms django-views

在我的django应用程序的博客中,编辑现有条目会导致创建新条目。它应修改现有条目。

我有一个简单的模型:

class BlogEntry(models.Model):
    ...
    slug = models.SlugField(unique=True)

和一个简单的编辑形式:

class BlogEntryForm(forms.ModelForm):
...
slug = forms.CharField(required=False, widget=forms.HiddenInput())

class Meta:
    model = BlogEntry
    fields = (..., 'slug')

并且有点简化的观点也是直截了当的:

class BlogEditView(View):
    @method_decorator(login_required)
    def get(self, request, slug=None):
        context = {
            'user': request.user,
        }
        if slug is None:
            print('Creating new entry.')
            context['entry'] = BlogEntryForm()
            context['entry'].publication_date = datetime.datetime.now()
            return render(request, 'blog/edit.html', context)
        print('Using existing entry.')
        entry = get_object_or_404(BlogEntry, slug=slug)
        context['entry'] = BlogEntryForm(instance=entry)
        return render(request, 'blog/edit.html', context)

    @method_decorator(login_required)
    def post(self, request):
        blog_entry_form = BlogEntryForm(request.POST)
        if blog_entry_form.is_valid():
            blog_entry = blog_entry_form.save(commit=False)
            if blog_entry.slug is None or blog_entry.slug == '':
                print('New entry, slug is empty.')
                blog_entry.creation_date = datetime.datetime.now()
                blog_entry.slug = slugify(blog_entry.title) + '_' + hex(random.randint(0, 1e10))
            blog_entry.author = request.user
            blog_entry.save()
            return redirect(reverse('blog/article', args=[blog_entry.slug]))
        ...

get()中,我用打印件确认我正在使用正确的分支。如果条目存在,我使用实例设置条目。但是,在post()中,我总是选择新的分支。

布局具有典型的隐藏元素循环。

{% for hidden in form.hidden_fields %}
    {{ hidden }} hidden
{% endfor %}
但是,可疑的是,当我看到服务的html时,我没有看到slug条目,所以毫不奇怪它没有通过。

任何人都能看到我错过的东西吗?

1 个答案:

答案 0 :(得分:2)

您还应该将slug参数添加到post()方法中。这将允许您从数据库中获取要编辑的博客条目,并将此条目作为instance参数传递给表单:

@method_decorator(login_required)
def post(self, request, slug=None):
    blog_entry = BlogEntry.objects.filter(slug=slug).first()
    blog_entry_form = BlogEntryForm(request.POST, instance=blog_entry)
    ...

更新:要将slug参数传递给post()方法,您应该使用action标记的空<form>属性:< / p>

<form action="" method="POST">

在这种情况下,表单将提交到加载它的URL。因此,POST请求的slug参数将与GET相同。