1👍
You have some options:
1. OneToOneField
on various category models:
-
Pro:
allows other models to have FK toJob
model. E.g. you could retrieve all of a person jobs viaperson.jobs.all()
no matter which category. -
Con:
Allows instances of different categories to relate to the same Job instance: Extra work is needed to maintain data integrityMore tables, more joins, slower queries
Adding a category always entails a migration!
2. Multi-Table
inheritance:
Uses OneToOneField
under the hood.
-
Pro:
as above + but each instance of a category will autocreate its ownJob
instance, so no collisions between categories. -
Con:
More tables, more joins, slower queries. Obscures some of the db stuff that’s going on.Adding a category always entails a migration!
3. Job
as an abstract base model
-
Pro: Single table for each category, faster queries
-
Con: separate relations need to be maintained for each category, no grouping possible at the db level.
Adding a category always entails a migration!
4. Put all the category specific fields in Job
(and make them nullable)
-
Pro: One Table, easy relations, Queries for special categories via filter on
category
field still possible.You can use specific model managers to handle categories:
Job.tutoring.all()
Possibly many categories share various subsets of fields
No overengineering, easy maintainability.
Adding a new category will only require a migration if it requires a field that is not there yet. You could have a generic
CharField
used by multiple categories for different semantic purposes and access it viapropertys
with meaningful names. These cannot, however, be used in filters or qs-updates.
À la:
class Job(models.Model):
# ...
attribute = models.CharField(...)
def _get_attribute(self):
return self.attribute
def _set_attribute(self, value):
self.attribute = value
# for shopping
shop_name = property(_get_attribute, _set_attribute)
# for babysitting
family_name = property(_get_attribute, _set_attribute)
# then you can use
babysitting_job.family_name = 'Miller'
- Con: Some fields are null for each job
While options 1-3 may better model the real world and make you feel good about the sophisticated model structure you have cooked up, I would not discard option 4 too quickly.
If the category fields are few and commonly shared between categories, this would be my way to go.
0👍
The optimal thing to do would be to use a OneToOneField. Before further explanation, I’ll just use this example:
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length=30)
class Item(models.Model):
menu = models.OneToOneField(Menu)
name = models.CharField(max_length=30)
description = models.CharField(max_length=100)
Menu here could compare to your Job model. Once an item in the menu is chosen, the Menu model basically extends the chosen Item’s fields. Item here can be compared to your Job category.
You can read more on this stuff here.
- How to implement chart.js with each field in the model? Django
- Django: showing many to many additional fields in template
- I couldn't store the values in database from the custom form in HTML page. Using Django
- Need Assistane in converting django model admin save method to Django Rest Framework