Pierre de LESPINAY
Pierre de LESPINAY

Reputation: 46158

Django - Update certain fields of a ModelForm

Model:

class Session(models.Model):
  tutor = models.ForeignKey(User)
  start_time = models.DateTimeField()
  end_time = models.DateTimeField()
  status = models.CharField(max_length=1)

Form:

class SessionForm(forms.ModelForm):
  class Meta:
    model = Session
    exclude = ['tutor']

Testing:

>>> ses = Session.objects.get(pk=1)
>>> ses
<Session: Robert - 2012-04-18 13:00:00>
>>> form = SessionForm(instance=ses)

Now for example, I'd like to update only the status of this instance and save it.
How can I do that ?


edit

Template:

<form action="fhjsdhkl" method="POST">{{ csrf_token }}
  <input name="start_time" />
  <input name="end_time" />
</form>

Trying to post only these 2 fields:

if request.method == 'POST':
  form = SessionForm(request.POST)
  if request.POST['id']:
    try:
      s = Session.objects.get(pk=request.POST['id'])
      form.instance = s
    except Session.DoesNotExist:
      pass
  if form.is_valid():
    form.save()

The Session could not be changed because the data didn't validate.

The error return by the form is

status - This field is required

The fields that I need to update are not fixed, and I'd like to avoid posting all the fields each time. Do I have to make a different form for each case ?

Upvotes: 4

Views: 4956

Answers (1)

James R
James R

Reputation: 4656

Edit 2: The old answer is irrelevant

if request.method == 'POST':
  form = SessionForm(request.POST)
  if request.POST['id']:
    try:
      s = Session.objects.get(pk=request.POST['id'])
      form.instance = s
    except Session.DoesNotExist:
      pass
  if form.is_valid():
    form.save()

Ok, you have a number of things going on here:

1.

This line should be like this:

form = SessionForm(request.POST, instance = s)

2.

You should move the session object up:

if request.method == 'POST':
    s = get_object_or_404(Session, pk=request.POST['id'])
    form = SessionForm(request.POST, instance = s)

If you do the try and except method below, you will raise validation errors whenever that object doesn't exist. Throw a 404 instead. Docs are here on the above shortcut: https://docs.djangoproject.com/en/1.0/topics/http/shortcuts/#get-object-or-404 You will need to import it if you haven't already.

Now you can valuidate it and save it:

if request.method == 'POST':
    s = get_object_or_404(Session, pk=request.POST['id'])
    form = SessionForm(request.POST, instance = s)
    if form.is_valid():
        form.save()

3.

Furthermore, you should not do this: if request.POST['id'] as strings are never False, even empty strings. For example, try this in IDLE:

>>> '' == True
>>> '' == False

>>> 'a' == True
>>> 'a' == False

You will note this always evaluates to False.

So, what you view was never actually creating the reference model.

Upvotes: 5

Related Questions