Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django Model Not Updating After Calling .save()

Tags:

python

django

My model won't update after save() is called in my view. Looking into several places (here, here) didn't yield any answers for my case. My model does contains a ManyToManyField:

Model:

class Event(models.Model):
    name = models.CharField(max_length=120)
    date = models.DateTimeField(auto_now=False, auto_now_add=False)
    attendees = models.ManyToManyField(Employee)
    approval = models.ForeignKey(EventStatus, default=2)

    def __unicode__(self):
        return self.name

    def approve_url(self):
        return reverse("RGAU:EventApprove", kwargs={"id": self.id})

View:

def EventApprove(request, id=None, **kwargs):

    instance = get_object_or_404(Event, id=id)

    instance.approval.id = 3
    instance.save()

    messages.success(request, "Event Approved")
    return redirect("RGAU:UserDashboard")

The goal is to have the Event instance updated to "Approved" when a button is pushed on the webpage (hence the view EventApprove).

instance.approval.id is suppose to assign the correct approval status id but the save is not committed.

What am I doing wrong?

like image 447
NickBraunagel Avatar asked Mar 10 '23 04:03

NickBraunagel


1 Answers

You can do this two different ways. If you have only the pk (id) value of the related object you want to associate, use the fieldname_id syntax, like this:

instance.approval_id = 3
instance.save()

If you have an instance of the relation handy, you can just assign it:

approved = EventStatus.objects.get(id=3)
instance.approval = approved
instance.save()

Either way, your instance.approval will now be associated with the EventStatus having the id=3.

To explain further: instance.approval is a property of instance which contains the associated instance of EventStatus. If you then further dig into that by using instance.approval.id you are now touching the EventStatus instance and changing its id, which you really don't want to do.

instance.approval_id is a little magic where Django allows you to directly set the database column value that associates the two models.. bypassing the need to actually fetch the instance of your EventStatus from the database just to be able to associate it with Event. It is handy in situations like this when you are using well known reference id values that never change. But even so it's good practice to define them somewhere, eg:

class EventStatus(models.Model):
    APPROVED = 3

    ... etc etc...

Then instead of using instance.approval_id = 3 you can use instance.approval_id = EventStatus.APPROVED which is a lot easier to understand later.

like image 95
little_birdie Avatar answered Mar 21 '23 07:03

little_birdie