[Baypiggies] Django | Clean Design Question

Glen Jarvis glen at glenjarvis.com
Mon May 11 20:30:01 CEST 2009

Since I've been using Django this past year, I've slowly learned how  
to be more dynamic and DRY using the Django framework.

For example, in the very beginning, if I were using newforms (now  
forms), I would create a form that mimic'ed the model (unless  
modelforms were really easy).

Now, I've been using model forms and doing something like this for  
quite a while:

from django.forms import ModelForm

class PIGDemoForm(ModelForm):
     class Meta:
         model = Grant

     def __init__(self, *args, **kwargs):
         super(PIGDemoForm, self).__init__(*args, **kwargs)
         self.fields['date_received'].widget =\
             forms.TextInput(attrs={'class': 'date-pick'})

Now, I have two models, we'll call model1 and model2. And, they both  
have a name attribute. Because I normalize data, I never do something  
like "model1.model1_name", but instead "model1.name." But, it's  
getting me in trouble.

Both forms have a 'name' attribute. And, both forms are in a template  
together. (I mean that both form instances are created for the  
specific instance of the model in question, and are displayed together  
(very interleaved) in a template). The response that I get back, via  
request.POST instantiates both forms:

form1 = Form1(request.POST, instance=blah1)
form2 = Form2(request.POST, instance=blah2)

[Note I'm translating this from a domain specific problem to generic  
(form1, form2, etc.) on the fly. There's room for error]

Now, if request.POST has only one 'name' then form1 and form2 are  
getting the same name, obviously causing a problem.

My question is specific to a better design. I see the following  
options (did I miss any):
1) Manually create one form that mimics model1 and model2 together  
(violates DRY, and makes verbose and less useable code)

2) Change my model names to be something like (model1.model1_name,  
model2.model2_name). This violates normalization rules (and has an  
impact on other code already written).

3) Try 'hacking' the form temporarily... something like:

    def __init__(self, *args, **kwargs):
        super(blah blah blah)

        blah blah

        self.fields['grant_name'] = self.fields['name']

        If this third option is chosen, I need to either:

         a) move the self.fields['grant_name'] back to  
self.fields['name'] before using the form shortcut save() method, [and  
I scratch my head on how. Do I need to look at the pre-save signals,  
         b) Create a new model manually, specifying a mapping of  
"self.cleaned_data['grant_name']" to the model's "name" property. This  
has the same feel (redundant and less dynamic) as the above solutions,  
but may be the best we can do in this situation.

Please note that the database is laid out in a very normalized manner  
per the request of the IT department of my customer. The user,  
however, doesn't understand these differences *at all* and just wants  
his data to look like it does when he types in a spreadsheet. So,  
there are competing design paradigms coming from two different people.  
That difference is something we're going to have to live with in this  

When I start getting into this kind of place, I think it's time for me  
to stop, put the keyboard down, and think... This is a very common  
design pattern: what do most people do?

Thanks for listening and any fresh perspective would be welcomed.

All the best,

Glen Jarvis
"You must be the change you wish to see in the world." -M. Gandhi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/baypiggies/attachments/20090511/81a3fabd/attachment.htm>

More information about the Baypiggies mailing list