Forms for updating a compound model

19 views
Skip to first unread message

David Flitney

unread,
Jul 4, 2012, 5:04:00 AM7/4/12
to django...@googlegroups.com
I've a couple of models: Bill which is linked to potentially several BillDetail models.

class Bill(models.Model):
    series_number = models.IntegerField(primary_key=True)
    status = models.CharField(max_length=27)
    date = models.DateField(null=True, blank=True)
    project_code = models.CharField(max_length=30)
    invoice_number = models.IntegerField(null=True, blank=True)
    lastmodified = models.DateTimeField(auto_now=True)
    class Meta:
        db_table = u'bill'
    
class BillDetail(models.Model):
    scan_uid = models.ForeignKey(Scan, db_column='scan_uid')
    charge = models.IntegerField()
    series_number = models.ForeignKey(Bill, db_column='series_number')
    lastmodified = models.DateTimeField(auto_now=True)
    class Meta:
        db_table = u'bill_detail'         

Appologies for the messy models this is work on a legacy database so I need to accommodate existing apps. 


I'd like to build a form which allows the user to only modify 1) the charge fields for each BillDetail and 2) the status field for the associated Bill, i.e., all I want to do is provide summary text for the Bill instance with an editable status field, and for each associated BillDetail some descriptive text and an editable charge field.

Now I was able to trivially create a bill view using the modelformset_factory and inlineformset_factory functions but that gives full edit functionallity for all the fields of all model instances. All the examples I've found also imply that forms only make sense for editing the whole model. I really don't understand that since updating restricted parts of a model must be a really common problem, e.g., reviewing a shopping cart where you might want to adjust each item count but not give the customer the chance to replace an item with any other item from your inventory!

One trick I've tried was to write a custom form and pass that as the form attribute in my formset_factory constructor, only this doesn't then seem to have access to the instance data in the way I expected.

Can this be done using the model related formsets? Does on have to create a custom forms.Form and manually populate all the data. Any guidance on a nice way of achieving this would be much appreciated.

-- 
Dave Flitney
Oxford Centre for Functional MRI of the Brain
E:fli...@fmrib.ox.ac.uk W:+44-1865-222713 F:+44-1865-222717
URL: http://www.fmrib.ox.ac.uk/~flitney




Tomas Neme

unread,
Jul 4, 2012, 10:07:52 AM7/4/12
to django...@googlegroups.com
I'm sorry to tell you that ModelForms don't seem to have this functionality, but I'm happy to tell you that ModelAdmins do.

What it does, basically, is to return this:

{
     'label': label_for_field(field, self.opts.model, self.opts),
     'widget': {
       'is_hidden': False
     },
     'required': False
}

when there's a field marked as readonly, so it can transparently be used from the templates.

I recommend you go look at the code in django.contrib.admin.helpers.InlineAdminFormSet to get a feel of what you can do.

Annd... looking around, I found a ReadonlyWidget, look at the first answer here: http://stackoverflow.com/questions/2931884/odd-behavior-in-django-form-readonly-field-widget

--
"The whole of Japan is pure invention. There is no such country, there are no such people" --Oscar Wilde

|_|0|_|
|_|_|0|
|0|0|0|

(\__/)
(='.'=)This is Bunny. Copy and paste bunny
(")_(") to help him gain world domination.

yak-man

unread,
Jul 4, 2012, 12:11:57 PM7/4/12
to django...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages