Danger with django ModelForms and related names

There is a danger in extending your ModelForms with fields if you don’t take care of your naming. Take for example these models. The forms represents a simple batch emailing module.

#!/usr/bin/python/

class EmailBatch(models.Model):
    body = models.TextField()
    subject = models.CharField(max_length=400)

class Email(models.Model):
    batch = models.ForeignKey(EmailBatch, null=False, related_name="emails")
    recipient = models.EmailField()

I wrote a simple form field called MultipleEmailField so the users can input several email addresses in a simple textarea. The resulting form is something like this:

#!/usr/bin/python/

class SendingForm(forms.ModelForm):
    emails = MultiEmailField(required=True)

    class EmailBatch:
        model = Delivery
        fields = ('body', 'subject', )

This appears to be alright, but isn’t. If you use this form you’ll get an AttributeError. The problem is in handling the “emails” field on the form. It’s not bound to any model, but the model actually contains something called emails (it’s set in the related_name part of the Email model). This can take some time to find :(

The bug is already fixed in django trunk, but for those of us trying to use a stable version we’ll just have to wait a little longer.

A simple fix is just to rename your field or related name

This entry was posted in django and tagged . Bookmark the permalink.

3 Responses to Danger with django ModelForms and related names

  1. what about including 2 self-referential M2M fields with Through table definitions in your mytest model? Apply the same rules above, avoiding naming conflicts and remembering to include related_names for each M2M field in your mytest model,

  2. Thanks for the article. I am new at python and this was a big help.

  3. This is great! Thanks for the article. I am new at django and this was a big help.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>