[Django]-Modeling a complex relationship in Django

4👍

Why not just have both types of category in one model, so you just have 3 models?

Site

Category
  Sites = models.ManyToManyField(Site)
  IsCommon =   models.BooleanField()

Item
  Category = models.ForeignKey(Category)

You say “Internally, those two type of Categories are completely identical”. So in sounds like this is possible. Note it is perfectly valid for a ManyToManyField to have only one value, so you don’t need “ForeignKey and a ManyToMany field on the same Category model” which just sounds like a hassle. Just put only one value in the ManyToMany field

👤James

1👍

As as alternative implementation you could use django content types (generic relations) to accomplish the connection of the items. A bonus for using this implementation is that it allows you to utilize the category models in different ways depending on your data needs down the road.

You can make using the site categories easier by writing model methods for pulling and sorting categories. Django’s contrib admin also supports the generic relation inlines.

Your models would be as follow:

Site(models.Model):
  label = models.CharField(max_length=255)

Category(models.Model):
  site = models.ManyToManyField(Site)
  label = models.CharField(max_length=255)

SiteCategory(models.Model):
  site = models.ForeignKey(Site)
  label = models.CharField(max_length=255)

Item(models.Model):
  label = models.CharField(max_length=255)
  content_type = models.ForeignKey(ContentType)
  object_id = models.PositiveIntegerField()
  content_object = generic.GenericForeignKey('content_type', 'object_id')

For a more in depth review of content types and how to query the generic relations you can read here: http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/

0👍

Caveat: I know Object-Relation mapping, Rails, and Python, but not Django specifically.

I see two additinal options:

  1. Thinking from a database point of view, I could make the table needed for the many-many relation hold an additional field which indicates a “common” vs. “site” relationship and add constraints to limit the type of “site” relationships. This can be done in Django, I think, in the section “Extra Fields on Many-To-Many Relationships.”

If you are at an earlier version of Django, you can still do this by making the many-many-table an explict model.

  1. Thinking from an object point of view, I could see splitting the Categories into three classes:

    BaseCategory

    CommonCategory(BaseCategory)

    SiteCategory(BaseCategory)

and then use one of Django’s inheritance models.

Leave a comment