nitimalh
nitimalh

Reputation: 961

Django UpdateView creates a new object instead of updating the current object

Everytime I use UpdateView and try to change some attributes it creates a new object in my database by using a new unique Primary Key. My model is as below.

class Delivery(models.Model):
    created_date = models.DateTimeField('date created', editable=False)
    modified_date = models.DateTimeField('modified', editable=False)
    user_name = models.ForeignKey(User, null=False)
    stream_name = models.CharField(max_length=50, null=False)
    view_name = models.CharField(max_length=100, null=False, blank=True)
    activity_name = models.CharField(max_length=100, null=False, blank=True)
    jira = models.URLField()
    codereview = models.URLField()
    related_streams = models.CharField(max_length = 100, choices=sorted(streams()))
    description = models.TextField(null=False,blank=True)
    status = models.BooleanField(default=False, blank=False)

    class Meta:
        verbose_name = "Delivery"
        verbose_name_plural = "Deliveries"
        unique_together = (("user_name", "view_name", "activity_name"),)

For the form I am using the ModelFactoryForm that UpdateView uses by default to pick out a form_class using the model itself.

class UpdateEntryView(UpdateView):
    template_name = 'tracker/update.html'
    model = Delivery
    success_url = reverse_lazy('table_view')
    status = StreamStatus()
    fields = ['stream_name','view_name','activity_name','jira','related_streams','description','status']

    def get_context_data(self, **kwargs):
        ctx = super(UpdateEntryView, self).get_context_data(**kwargs)
        ctx['locked'] = self.status.getLocked()
        ctx['unlocked'] = self.status.getUnlocked()
        return ctx

The HTML template is as below :

...
{% block content %}
<form action="/tracker/entry/" method="post" class="form">
    {% csrf_token %}
    <div class="form-goup">
        <div class="panel panel-default">
            <div class="panel-heading">Enter the codereview link and let the machine do the work for you ...</div>
            <div class="panel-body">
                <div class="input-group">
                    <i class="glyphicon glyphicon-link input-group-addon" aria-hidden="true"></i>
                    <input type="text" class="form-control" name="codereview"  placeholder="Codereview link">
                </div>
            </div>
        </div>
        <hr>
        <div class="panel panel-default">
            <div class="panel-heading">Add an entry manually ...</div>
            <div class="panel-body">
                {% bootstrap_form form %}
            </div>
        </div>
        <hr>
        {% buttons %}
        <button type="submit" class="btn btn-primary btn-block">
        {% bootstrap_icon "lock" %} Submit
        </button>
        {% endbuttons %}
    </div>
</form>
{% endblock %}
...

Is this a flaw in UpdateView or is it something on my part which is screwing this up.

Upvotes: 2

Views: 3557

Answers (3)

Sahan
Sahan

Reputation: 196

Even this question is already being answered, it is worth noticing another scenario that can accidentally generate this issue.

When you are using different form field as Primary Key in your form and then try to update, it will also create a new object. For example,

class Classroom(models.Model):
    owner = models.ForeignKey(User, on_delete=models.CASCADE)
    name = models.CharField(max_length=250, primary_key=True)

If you try to update this model object with UpdateView (changing the name field) it will create a new object. Because you are trying to change the Primary key (in this case name) and that is not possible.

Upvotes: 0

wobbily_col
wobbily_col

Reputation: 11889

The line in your template is going to post it to the "/tracker/entry/" url, without a PK specified, I think this is what is causing your problem.

Update views should include a PK, or id, or slug in the URL, so Django knows what object to update.

Remove the url, and it will POST back to the same place as the GET.

<form action="" method="post" class="form">

Upvotes: 4

Erik
Erik

Reputation: 898

Is it possible your url is pointing to the CreateView instead of the UpdateView?

Upvotes: 8

Related Questions