I have the following Django models: -
class Company(models.Model):
name = models.CharField(max_length=50)
is_active = models.BooleanField(db_index=True)
class Phase(models.Model):
company = models.ForeignKey(Company)
name = models.CharField(max_length=50)
is_active = models.BooleanField(db_index=True)
class Process(models.Model):
company = models.ForeignKey(Company)
name = models.CharField(max_length=50)
phases = models.ManyToManyField(Phase, through='ProcessPhase')
is_active = models.BooleanField(db_index=True)
class ProcessPhase(models.Model):
process = models.ForeignKey(Process)
phase = models.ForeignKey(Phase)
order = models.PositiveIntegerField(help_text="At what step of your process will this phase occur?", unique=True)
A "company" has its "processes" and "phases". A process (of a company) is comprised of one or more phases (of the company). Each phase associated with a process has an "order". The requirement is that: -
So I need to know: -
a) how to specify some "unique"s in the model definition to fulfill the above requirements;
b) what uniqueness, if any, is automatically implied by a ManyToManyField?
In your case, since you say "A process (of a company) is comprised of one or more phases (of the company)", it seems like you should have a structure like:
Company <----* Process <----* Phase
Company has its Processes, Process has its Phases. It's not really a ManyToMany
relation, it's OneToMany
(Process has many Phases, but each Phase is connected to one Process).
If so, you should have
class Phase(models.Model):
process = models.ForeignKey(Process, null=True) # based on your comment, if a Phase does not belong to a Process, leave it null.
phase = models.ForeignKey(Phase)
order = models.PositiveIntegerField(help_text="At what step of your process will this phase occur?")
class Meta:
unique_togather = ("process", "order")
The unique_together
in Meta
class is what you want, I think. It enforces both in admin and on database level the uniqueness of those 2 fields together.
edit:
(ForeignKey
field can be null - see this)
based on your comment:
Don't use ManyToMany
, as it auto-generates the "table-in-the-middle", while you need it specific for your needs. Instead, try defining the different model (together with your Company
, Phase
and Process
):
class PhaseOrder(models.Model):
process = models.ForeignKey(Process)
phase = models.ForeignKey(Phase)
order = models.PositiveIntegerField(help_text="At what step of your process will this phase occur?")
class Meta:
unique_together = (("process", "order"), ("process", "phase"))