Ok, so this isn’t purely Django, but we do model our relational databases using Django (what a tremendous feature it is!).
I’m deliberating as to how to model a particular concept. The concept is quite simple. A test, for example a blood test has a category and it may have a sub-category. A sub-category always has a category.
One possible way I could this is:
class Category(models.Model): pass class SubCategory(models.Model): category = models.Foreignkey(Category, on_delete=models.CASCADE) class Test(models.Model): category = models.Foreignkey(Category, on_delete=models.CASCADE) sub_cat = models.Foreignkey(SubCategory, null=True, on_delete=models.CASCADE)
This is functional, but something about it irks me, namely that you could have a Test record that has a relation to both a
SubCategory and a
Category when you should really just be able to access the record by
Another way of doing it is to drop
category from the
Test model and create a SubCategory record which is for all intents and purpose a record to indicate that the test doesn’t have a sub-category. But this also doesn’t seem correct to me. It feels like a bit of a hack. As an example of what I mean:
>>>> test = Test.objects.get(my_test) >>>> test.sub_category <SubCategory: I am a placeholder category> >>>> test.sub_category.category <Category: Acidity Tests>
The third option which has popped into my head is to create two Test models,
SubCategory test. This however doesn’t seem very normalised to me, as both the
SubCategory models will be identical.
The fourth option, and the one I am using now, is to have a many-to-many relation which is illustrated in the code below:
class Test(models.Model): pass class Category(models.Model): tests = models.ManyToManyField(Test, on_delete=models.CASCADE) class SubCategory(models.Model): tests = models.ManyToManyField(Test, on_delete=models.CASCADE)
The first issue with this is that the relationship is not a many-to-many, it is in fact a 1 to many relationship, so with the above, I have unnecessary tables and complexity.
As you can probably tell, I’m a little unsure as to which way I’m going to go, so perhaps there is someone here who can look at this problem with a fresh pair of eyes.