Python Django表单创建新实例,而不是更新现有实例
我看到这个问题在这里被问了很多次,但我不明白为什么它在我的情况下不起作用。 我有以下视图代码:Python Django表单创建新实例,而不是更新现有实例,python,django,Python,Django,我看到这个问题在这里被问了很多次,但我不明白为什么它在我的情况下不起作用。 我有以下视图代码: def edit(request, coffee_id=None): coffee = get_object_or_404(Drink, pk=coffee_id) if coffee_id else Drink() if request.method == 'POST': form = CoffeeForm(request.POST, instance=coffee) if form
def edit(request, coffee_id=None):
coffee = get_object_or_404(Drink, pk=coffee_id) if coffee_id else Drink()
if request.method == 'POST':
form = CoffeeForm(request.POST, instance=coffee)
if form.is_valid():
form.save()
return HttpResponseRedirect(urlresolvers.reverse('coffee:index'))
else:
form = CoffeeForm(instance=coffee)
return render(request, 'edit.html', {'coffee_form': form})
这应该是为了创建一个新的coffee实例,或者如果数据库中存在参数中给定的coffee_id,则更新一个新实例
然而,即使数据库中存在coffee_id,也始终会创建一个新的coffee实例
我还尝试在不保存表单的情况下保存咖啡实例,但它也会这样做
有什么我做错了吗?我应该在模型中设置一些特殊的东西来允许更新吗
编辑
这是饮料单
class CoffeeForm(forms.ModelForm):
class Meta:
model = Drink
fields = ('time', 'location', 'type')
def __init__(self, *args, **kwargs):
super(forms.ModelForm, self).__init__(*args, **kwargs)
coffee_category = Category.objects.get(name='coffee')
coffee_drink_types = DrinkType.objects.filter(category=coffee_category.id)
self.fields['type'].choices = ((x.id, str(x)) for x in coffee_drink_types)
饮料型号:
class Drink(models.Model):
time = models.DateTimeField('time', default=datetime.datetime.now)
location = models.ForeignKey(Location)
type = models.ForeignKey(DrinkType)
**编辑**
添加URL:
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^edit/$', views.edit, name='edit'),
url(r'^edit/(?P<coffee_id>[0-9]*)/$', views.edit, name='edit')
]
urlpatterns=[
url(r'^$',views.index,name='index'),
url(r“^edit/$”,views.edit,name='edit'),
url(r'^edit/(?P[0-9]*)/$,views.edit,name='edit')
]
如果给定id的饮料不存在,则获取\u object\u或\u 404错误
您确定已根据/edit/1进行过帐吗?因为如果表单操作没有ID,就会创建一个新的饮料
我建议您使用单独的创建和编辑视图。可能会使用基于类的视图,但如果您有理由不使用它们,类似的方法可能会奏效:
def create_coffee(request):
if request.method == 'POST':
form = CoffeeForm(request.POST)
if form.is_valid():
coffee = form.save()
return redirect(reverse('edit_coffee', kwargs={'coffee_id': coffee.pk}))
else:
form = CoffeeForm()
return render(request, 'create.html', {'coffee_form': form})
def edit_coffee(request, coffee_id=None):
coffee = Drink.objects.filter(pk=coffee_id).first()
if not coffee:
return redirect(reverse('create_coffee'))
else:
if request.method == 'POST':
form = CoffeeForm(request.POST, instance=coffee)
if form.is_valid():
form.save()
else:
form = CoffeeForm(instance=coffee)
return render(request, 'edit.html', {'coffee_form': form})
调用
super
时,应使用CoffeeForm
,而不是ModelForm
class CoffeeForm(forms.ModelForm):
class Meta:
model = Drink
fields = ('time', 'location', 'type')
def __init__(self, *args, **kwargs):
super(CoffeeForm, self).__init__(*args, **kwargs)
我不知道你是否还在检查这个问题,我发现这个是在寻找同样的问题,我设法解决了这个问题。 在我的例子中,问题是我对新对象和现有对象使用了相同的模板,表单返回并创建了新实例,我解决了这个问题,此时使用多个模板创建了多个视图 当我从表单中删除我的
action=“/add”
时,我发现什么也没有发生:)。我发现您正在使用相同的模板,并且没有从视图中更改它,因此您可能也需要这样做。
如果你不能解决这篇文章,你的模板和我很乐意提供帮助,因为它可以帮助我学习django!:) 也有同样的问题,我的原因是在forms.py中重写默认方法form.save()。所以我决定使用两种方法(保存和更新)。Update方法应从默认的save()方法导入
super(ArticleForm,self).save(*args,**kwargs)
这不是必需的,但对我来说是必要的,因为我应该保存一些不是来自表单的数据
def save(self, *args, **kwargs):
new_article = Article.objects.create(
title=self.cleaned_data['title'],
text=self.cleaned_data['text'],
image=self.cleaned_data['image'],
author_id=self._user.id
)
return new_article
def update(self, article_id, *args, **kwargs):
super(ArticleForm, self).save(*args, **kwargs)
new_article = Article.objects.get(id=article_id)
return new_article
此方法无法返回任何内容,但我需要views.py中的新_article对象
但你可以用另一种方式。只需在表单的definit中定义author\u id字段
在这里你可以了解更多信息:你能展示一下咖啡配方和饮料模型吗?我编辑了这篇文章。t您确定正在将
coffee\u id
传递给视图吗?你能显示你的URL吗?我添加了URL,我认为它正确地传递到视图中,因为表单预先填充了咖啡数据。只是当我再次保存它时(无论是否更改),它会创建一个新条目,而不是更新新条目。您的评论是对的。但是我仍然创建了新条目:)谢谢你的回答。我认为可以使用django使用单个视图编辑和创建对象,但这可能不是一个好的模式。。。另外,我在edit\u coffee
方法中没有看到可以修复创建而不是更新问题的代码。是否根据/edit/123发布?你也许可以通过一些打印语句来解决这个问题。