Django add extra field to a ModelForm generated from a Model
Asked Answered
N

2

73

I have to generate a FormSet from a model but I need to insert an "extra value" in to every form.

Specifically, I have a JApplet that generates some Markers and Paths on a image, and POST it on the server.

In my model lines are composed from two Markers. But when I POST it, because I'm using the id generated from the JApplet and not from the database, I will not know from which Markers a Path will be composed.

So I thought to insert a "temporary id" on the Marker on the form, and do the correct arrangements in the view before saving the Path.

I thought about defining a custom form for the markers, but it not seems to be very DRY, and I don't want to came back to this if I change the Marker model.

Here is the form:

  class PointForm(forms.ModelForm):
    temp_id = forms.IntegerField()
    class Meta:
            model = Point

    def clean(self):
            if any(self.errors):
                    # Don't bother validating the formset unless each form is valid on its own
                    return

            ingresso = self.cleaned_data['ingresso']
            ascensore = self.cleaned_data['ascensore']
            scala = self.cleaned_data['scala']

            if (ingresso and ascensore) or (ingresso and scala) or (ascensore and scala):
                    raise forms.ValidationError("A stair cannot be a elevator or an access!!!") 
            return self

    def save(commit=True):
    # do something with self.cleaned_data['temp_id']
            super(PointForm).save(commit=commit)

And the model:

  class Point(models.Model):

    RFID = models.CharField(max_length=200, blank=True)

    x = models.IntegerField()
    y = models.IntegerField()

    piano = models.ForeignKey(Floor)

    ingresso = models.BooleanField()

The error:

  ViewDoesNotExist at /admin/
  Could not import buildings.views.getFloors. View does not exist in module buildings.views.
  Request Method:   GET
  Request URL:  http://127.0.0.1:8000/admin/
  Django Version:   1.4.1
  Exception Type:   ViewDoesNotExist
  Exception Value:  
  Could not import buildings.views.getFloors. View does not exist in module buildings.views.
  Exception Location:   /usr/local/lib/python2.7/dist-packages/django/core/urlresolvers.py in get_callable, line 101

The error is generated when I try to load the admin page, this page has no references at all with the form.

SOLUTION FOR EXCEPTION

Ok, I'll write here how to find out why Django was doing such a strange thing.

Here it's a correct way to find out what is the problem.

The exception was thrown because I forgot to add forms.py to the from django import forms.

Nourish answered 25/11, 2012 at 11:16 Comment(1)
And, if I remove getFloors from url.py it calls an error of missing view on the next url in url.py... Is this a bug?Nourish
M
94

You can add a field to a ModelForm. Unless you add a field named temp_id to your model you do not need to change this form when you change you model.

Example (with a model named Point):

class PointForm (forms.ModelForm):
    temp_id = forms.IntegerField()

    class Meta:
        model = Point

    def save(self, commit=True):
        # do something with self.cleaned_data['temp_id']
        return super(PointForm, self).save(commit=commit)

UPDATE: Forgot self in def save() and changed modelname to Point

Markus answered 25/11, 2012 at 12:13 Comment(3)
I have tried this approach before @relekang, but I get a Could not import buildings.views.getFloors. View does not exist in module buildings.views. When I remove the line temp_id = forms.IntegerField() all works well...Nourish
Looks like you are having problems with circular imports.Markus
Somehow doing this resulted in my clean method not being run and I can't figure out why. UGH.Volauvent
L
5

To follow up relekang's answer, I had to be reminded to also return the last line as shown, so that the object's get_absolute_url() method could be automatically called on submission of the form:

return super(PointForm, self).save(commit=commit)
Lennon answered 18/3, 2015 at 9:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.