Skip to content Skip to sidebar Skip to footer

How To Model A Foreign Key In A Reusable Django App?

In my django site I have two apps, blog and links. blog has a model blogpost, and links has a model link. There should be a one to many relationship between these two things. There

Solution 1:

If you think the link app will always point to a single app then one approach would be to pass the name of the foreign model as a string containing the application label instead of a class reference (Django docs explanation).

In other words, instead of:

classLink(models.Model):
    blog_post = models.ForeignKey(BlogPost)

do:

from django.conf import setings
classLink(models.Model):
    link_model = models.ForeignKey(settings.LINK_MODEL)

and in your settings.py:

LINK_MODEL = 'someproject.somemodel'

Solution 2:

I think TokenMacGuy is on the right track. I would look at how django-tagging handles a similar generic relationship using the content type, generic object_id, and generic.py. From models.py

classTaggedItem(models.Model):
    """
    Holds the relationship between a tag and the item being tagged.
    """
    tag          = models.ForeignKey(Tag, verbose_name=_('tag'), related_name='items')
    content_type = models.ForeignKey(ContentType, verbose_name=_('content type'))
    object_id    = models.PositiveIntegerField(_('object id'), db_index=True)
    object       = generic.GenericForeignKey('content_type', 'object_id')

    objects = TaggedItemManager()

    classMeta:
        # Enforce unique tag association per object
        unique_together = (('tag', 'content_type', 'object_id'),)
        verbose_name = _('tagged item')
        verbose_name_plural = _('tagged items')

Solution 3:

Anoher way to solve this is how django-mptt does this: define only an abstract model in a reusable app(MPTTModel), and require to inherit it with defining some fields (parent=ForeignKey to self, or whatever your app usecase will require)

Solution 4:

Probably you need to use the content types app to link to a model. You might then arrange for your app to check the settings to do some additional checking to limit which content types it will accept or suggest.

Solution 5:

I'd go with generic relations. You can do something like select_related, it just require some extra work. But I think it's worth it.

One possible solution for generic select_related-like functionality:

http://bitbucket.org/kmike/django-generic-images/src/tip/generic_utils/managers.py

(look at GenericInjector manager and it's inject_to method)

Post a Comment for "How To Model A Foreign Key In A Reusable Django App?"