我已经看到这个问题在这里问了很多时间,但我无法弄清楚为什么它在我的案例中不起作用。 我有以下视图代码:
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_id,则应该创建一个新的咖啡实例或更新一个新实例。
然而,即使数据库中存在coffee_id,也始终会创建一个新的咖啡实例。
我还尝试保存咖啡实例而不保存表单,但它也是如此。
有什么东西我做错了吗?我应该在模型中设置一些特殊的东西以允许更新吗?
修改
这是饮料表格
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)
**编辑**
添加网址:
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')
]
答案 0 :(得分:1)
调用CoffeeForm
时,您应该使用ModelForm
,而不是super
。
class CoffeeForm(forms.ModelForm):
class Meta:
model = Drink
fields = ('time', 'location', 'type')
def __init__(self, *args, **kwargs):
super(CoffeeForm, self).__init__(*args, **kwargs)
答案 1 :(得分:0)
get_object_or_404错误。
你确定对/ edit / 1进行了POST吗?因为如果表单操作没有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})
答案 2 :(得分:0)
不知道你是否还在检查这个问题,我发现这也在寻找同样的问题,我设法解决了这个问题。 在我的情况下,问题是我为新对象和现有对象使用了相同的模板,并且表单返回并创建了新实例,我解决了此时使用多个模板创建多个视图。
我进入正轨的那一点是当我从表单中删除action="/add"
时,我发现没有任何反应:)。我看到您使用相同的模板而不是从视图中更改它,因此您可能还需要这样做。
如果你无法解决这个帖子你的模板,我很乐意提供帮助,因为它可以帮助我学习django! :)
答案 3 :(得分:0)
有同样的问题,我的原因是在Forms.py中覆盖了默认方法form.save()。因此,我决定采用2种方法(用于保存和更新)。更新方法应继承默认的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中添加new_article对象
但是您可以采取另一种方式。只需在表单的def init 中定义author_id字段即可。
在这里您可以了解更多信息:Habr