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发布?你也许可以通过一些打印语句来解决这个问题。