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 test.subcategory.category
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, CategoryTest
and SubCategory
test. This however doesn’t seem very normalised to me, as both the CategoryTest
and 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.