pythondjangodjango-modelsdjango-inheritance

Django - Is it possible in a intermediate table to use an inherited ForeignKey for the target model?


I'm using django 1.4 and I have the following models:

class Newsletter(EmailTemplate):
    receivers = models.ManyToManyField(User, related_name='newsletters',
                                       db_index=True,
                                       through='NewsletterReceiver')

class EmailReceiver(models.Model):
    user = models.ForeignKey(User, db_index=True)

class NewsletterReceiver(EmailReceiver):
    newsletter = models.ForeignKey(Newsletter, db_index=True)

When I create a Newsletter object in my view by doing something like this:

newsletter = form.save(commit=False)
newsletter.receivers.clear()
receivers = form.cleaned_data['receivers']
for receiver in receivers:
    newsletter_receiver = NewsletterReceiver(user=receiver, newsletter=newsletter)
    newsletter_receiver.save()

form.save_m2m()
newsletter.save()

I can see that all the both the Newsletter object ant the NewsletterReceiver object have been created. Using ipython if I query both the user and the newsletter from the newly created NewsletterReceiver everything is fine, but if I query the receivers from the Newsletter instance then django complains about something I do not understand:

In [2]: nr = NewsletterReceiver.objects.all()[0]

In [3]: nr.user
Out[3]: <User: 3>

In [4]: nr.newsletter
Out[4]: <Newsletter: Newsletter object>

In [5]: nr.newsletter.receivers
Out[5]: <django.db.models.fields.related.ManyRelatedManager at 0x10ea26f90>

In [6]: nr.newsletter.receivers.all()
Out[6]: 
<repr(<django.db.models.query.QuerySet at 0x10ee860d0>) failed:
django.db.utils.DatabaseError: column web_newsletterreceiver.user_id does not exist
LINE 1: ...N "web_newsletterreceiver" ON ("auth_user"."id" = "web_newsl...
                                                         ^
>

Is this because the ForeignKey to the target model is inherited? Is there a workaround for that or should I have to refactor the models?


Solution

  • I solved it by adding:

    class Meta:
        abstract = True
    

    to EmailReceiver model.