[英]Django form creates new instance instead updating a existing one
我在這里看到這個問題問了很多時間,但我不明白為什么它在我的情況下不起作用。 我有以下視圖代碼:
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')
]
調用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)
如果具有給定 id 的 Drink 不存在,則 get_object_or_404 出錯。
你確定 POST 是針對 /edit/1 完成的嗎? 因為如果表單操作沒有 ID,則會創建一個新的 Drink。
我建議您使用單獨的創建和編輯視圖。 可能使用基於類的視圖,但如果您有理由不使用它們,則可以使用以下方法:
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})
不知道你是否還在檢查這個問題,我發現這個是在尋找同樣的問題,我設法解決了這個問題。 在我的情況下,問題是我對新對象和現有對象使用了相同的模板,並且表單正在返回並創建新實例,我解決了此時使用多個模板創建多個視圖的問題。
當我從表單中刪除我的action="/add"
時,我開始走上正軌,但我看到沒有任何反應:)。 我看到您正在使用相同的模板並且沒有從視圖中更改它,因此您可能也需要這樣做。 如果你不能解決這個帖子你的模板,我很樂意提供幫助,因為它也可以幫助我學習 django! :)
有同樣的問題,我的原因是覆蓋了 forms.py 中的默認方法 form.save()。 所以我決定制作兩種方法(用於保存和更新)。 更新方法應該繼承默認的 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
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.