Django:编辑现有对象,但保存时新建
Django: edit existing object, but new on save
在我的 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 条目,所以它没有通过也就不足为奇了。
有人看到我遗漏了什么吗?
您还应该将 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)
...
UPDATE:要将 slug
参数传递给 post()
方法,您应该使用 [=18] 的空 action
属性=] 标签:
<form action="" method="POST">
在这种情况下,表单将提交到加载它的 url。因此 POST 请求的 slug
参数将与 GET 相同。
在我的 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 条目,所以它没有通过也就不足为奇了。
有人看到我遗漏了什么吗?
您还应该将 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)
...
UPDATE:要将 slug
参数传递给 post()
方法,您应该使用 [=18] 的空 action
属性=] 标签:
<form action="" method="POST">
在这种情况下,表单将提交到加载它的 url。因此 POST 请求的 slug
参数将与 GET 相同。