簡體   English   中英

Django 表單創建新實例而不是更新現有實例

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM