Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Django, how do you save multiple form fields into a single model field as a list of values using a ModelForm?

Given:

from django.db import models
class MyModel(models.Model):
    ...
    owners = models.CharField(max_length=255, blank=False)

where owners is a pipe-separated list of email addresses.

In the page, there are multiple <input> fields with the same name, so the server gets the values in an array.

The HTML code for the form was done by-hand and doesn't use built-in templates (such as form.as_p).

Can Django's ModelForms handle something like this?

What is the proper location to handle the data transformation, both when retrieving the model (do I have to make a custom models.Manager?) and when saving it (which save() method do I override? the Model's or the ModelForm's)?

--UPDATE FOR CLARIFICATION--

In the database:

+-----+---------------------------+-----+
| ... |           owners          | ... |
+-----+---------------------------+-----+
| ... | "[email protected]|[email protected]|[email protected]" | ... |
+-----+---------------------------+-----+

The form:

<form ... >
    ...
    <input type="text" name="owners" />
    <input type="text" name="owners" />
    <input type="text" name="owners" />
    ...
</form>
like image 587
Nikki Erwin Ramirez Avatar asked Dec 21 '22 16:12

Nikki Erwin Ramirez


2 Answers

You can use forms.MultiValueField and forms.MultiWidget. MultiValueField knows that your model's one field contains multiple discrete values and the MultiWidget widget knows how each discrete value should be presented. They'll handle creating unique names for your fields so that they can reconstruct the form from POST values and you won't have to override any form methods that provide implementation, i.e. you won't have to override save().

As you can see, the official docs are a bit thin on the topic. I suggest you take a peek at the code to figure out how everything is wired and what gets called when, since your requirements are always going to need a unique solution, i.e: how many emails will the field contain? Exactly two, so I can specify two CharField widgets by hand, or is it going to be between 0-2, so I have to dynamically construct everything depending on the value passed? If you need a good example as a starting reference, check out this SO question which contains a clean and easy to follow implementation.

Ideally, you'll want to have a PipedEmailAddressesField that extends CharField as your model's field, one that knows that it's storing piped email addresses. It should be able to construct it's own appropriate MultiValueField form field which should in turn construct it's own appropriate MultiWidget field.

like image 181
Filip Dupanović Avatar answered Dec 28 '22 07:12

Filip Dupanović


Here is an example of saving a modelform in a view: http://themorgue.org/blog/2008/05/14/django-and-modelform/ You can get the extra fields manually using request.POST['fieldname'] Hope this helped.

like image 32
endre Avatar answered Dec 28 '22 07:12

endre