[Python] Django UpdateView Creates New Object Instead of Updating the Existing One

Discussão em 'Python' iniciado por Stack, Abril 9, 2025.

  1. Stack

    Stack Membro Participativo

    I'm having an issue with my Django update view. Although I see the correct data on the update form (i.e. the GET request pre-fills the form with the existing article’s content), when I submit the form the original article isn’t updated—instead, a new article is created with a new uid, and the original still remains with its original uid.

    I’ve verified that:

    My update view initializes the ModelForm with the existing instance using the instance parameter.

    My URL configuration includes the primary key (uid) in the URL.

    Below is a simplified version of my code.

    views.py:

    from django.shortcuts import render, get_object_or_404, redirect
    from .models import Article
    from .forms import ArticleForm

    def ArticleUpdate(request, pk):
    # Fetch the existing article using the uid passed via URL
    article = get_object_or_404(Article, uid=pk)

    if request.method == 'POST':
    # IMPORTANT: The form is instantiated with the existing instance!
    form = ArticleForm(request.POST, request.FILES, instance=article)
    if form.is_valid():
    form.save() # Expect this to update, not create a new article
    return redirect('article-read', pk=article.uid)
    else:
    print("Form errors:", form.errors)
    else:
    form = ArticleForm(instance=article)

    context = {'form': form}
    return render(request, 'blog/article_form.html', context)


    urls.py:

    from django.urls import path
    from blog import views

    urlpatterns = [
    path('articles/create/', views.ArticleCreate, name='article-create'),
    path('articles/<str:pk>/', views.ArticleRead, name='article-read'),
    path('articles/<str:pk>/update/', views.ArticleUpdate, name='article-update'),
    ]


    Template (article_form.html):

    {% extends 'base.html' %}

    {% block content %}
    <h2>{% if form.instance.pk %}Update{% else %}Create{% endif %} Article</h2>
    <form method="POST" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
    <button type="submit">{% if form.instance.pk %}Update{% else %}Create{% endif %}</button>
    </form>
    {% endblock %}


    Article Model (models.py)

    class Article(models.Model):
    # author =
    # category =
    uid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    title = models.CharField(max_length=200)
    description = models.TextField(null=True, blank=True)
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
    return self.title


    AticleForm (forms.py)

    class ArticleForm(forms.ModelForm):
    class Meta:
    model = Article
    fields = '__all__'


    I’ve double‑checked that:


    • The form is submitted to the correct URL (the update URL with the article’s pk).


    • The view always passes the existing instance to the form on POST.


    • There is no duplicate URL pattern that might inadvertently route the POST to my create view.

    Despite all this, submitting the form ends up creating a new article rather than updating the original one.

    What I’ve Tried:


    • Verified the URL in the browser contains the correct pk.


    • Added print statements in the view to confirm the correct instance is being loaded.

    Confirmed that the form’s fields are correct and that the model’s primary key (a UUID field) is non‑editable.

    Has anyone encountered this behavior? Could it be a template issue (e.g., a hardcoded action attribute causing the POST to hit the wrong view), or is there something else I might be missing?

    Any guidance would be greatly appreciated.

    Environment:

    Django 5.2

    Python 3.12

    Article model uses a UUIDField as primary key (non‑editable)

    Thanks in advance!

    Continue reading...

Compartilhe esta Página