Django form creates new instance instead updating a existing one
<p>I've seen this question asked a lot of time here but I can't figure out why it doesn't work in my case.
I have the following view code:</p>

<pre><code>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})
</code></pre>

<p>This is supposed to create a new instance of coffee or to update a new one if coffee_id given in argument exists in database.</p>

<p>However even if coffee_id exists in database a new instance of coffee is always created.</p>

<p>I also tried to save the coffee instance without saving the form but it does the same.</p>

<p>Is there something that i'm doing wrong ? Should I set something special in the model to allow update ?</p>

<p><strong>Edit</strong></p>

<p>This is the Drink form</p>

<pre><code>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)
</code></pre>

<p>And the Drink model:</p>

<pre><code>class Drink(models.Model):
    time = models.DateTimeField('time', default=datetime.datetime.now)
    location = models.ForeignKey(Location)
    type = models.ForeignKey(DrinkType)
</code></pre>

<p>** Edit ** </p>

<p>Add the urls:</p>

<pre><code>urlpatterns = [
    url(r'^$', views.index, name='index'),
    url(r'^edit/$', views.edit, name='edit'),
    url(r'^edit/(?P&lt;coffee_id&gt;[0-9]*)/$', views.edit, name='edit')
]
</code></pre>

<p>get_object_or_404 errors out if the Drink with the given id doesn't exist.</p>

<p>Are you sure POSTing is done against /edit/1? Because if the form action doesn't have the ID, a new Drink is created.</p>

<p>I'd recommend you go with separate create and edit views. Possibly use class based views, but if you have reasons not to use them, something like this could work:</p>

<pre><code>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})
</code></pre>

python django