209👍
To handle One-To-Many relationships in Django you need to use ForeignKey
.
The documentation on ForeignKey
is very comprehensive and should answer all the questions you have:
https://docs.djangoproject.com/en/3.2/ref/models/fields/#foreignkey
The current structure in your example allows each Dude
to have one number, and each number to belong to multiple Dude
s (same with Business
).
If you want the reverse relationship, you would need to add two ForeignKey
fields to your PhoneNumber
model, one to Dude
and one to Business
. This would allow each number to belong to either one Dude
or one Business
, and have Dude
s and Business
es able to own multiple PhoneNumber
s. I think this might be what you’re after:
class Business(models.Model):
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
business = models.ForeignKey(Business)
59👍
In Django, a one-to-many relationship is called ForeignKey. It only works in one direction, however, so rather than having a number
attribute of class Dude
you will need
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
Many models can have a ForeignKey
to one other model, so it would be valid to have a second attribute of PhoneNumber
such that
class Business(models.Model):
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
business = models.ForeignKey(Business)
You can access the PhoneNumber
s for a Dude
object d
with d.phonenumber_set.objects.all()
, and then do similarly for a Business
object.
- [Django]-Is there a way to filter a queryset in the django admin?
- [Django]-VueJS + Django Channels
- [Django]-Rendering a value as text instead of field inside a Django Form
47👍
To be more clear – there’s no OneToMany in Django, only ManyToOne – which is Foreignkey described above. You can describe OneToMany relation using Foreignkey but that is very inexpressively.
A good article about it:
https://amir.rachum.com/blog/2013/06/15/a-case-for-a-onetomany-relationship-in-django/
- [Django]-Using django-admin on windows powershell
- [Django]-Django select_for_update cannot be used outside of a transaction
- [Django]-Django – getting Error "Reverse for 'detail' with no arguments not found. 1 pattern(s) tried:" when using {% url "music:fav" %}
31👍
Django is smart enough. Actually we don’t need to define oneToMany
field. It will be automatically generated by Django for you. We only need to define a foreignKey
in the related table. In other words, we only need to define ManyToOne
relation by using foreignKey
.
class Car(models.Model):
# wheels = models.oneToMany() to get wheels of this car [**it is not required to define**].
class Wheel(models.Model):
car = models.ForeignKey(Car, on_delete=models.CASCADE)
If we want to get the list of wheels of particular car, we will use Python’s auto generated object wheel_set
. For car c
you will use c.wheel_set.all()
.
- [Django]-How to change empty_label for modelForm choice field?
- [Django]-How to change site title, site header and index title in Django Admin?
- [Django]-Django render_to_string missing information
27👍
You can use either foreign key on many side of OneToMany
relation (i.e. ManyToOne
relation) or use ManyToMany
(on any side) with unique constraint.
- [Django]-Best way to integrate SqlAlchemy into a Django project
- [Django]-How to force application version on AWS Elastic Beanstalk
- [Django]-Django gives Bad Request (400) when DEBUG = False
16👍
While rolling stone‘s answer is good, straightforward and functional, I think there are two things it does not solve.
- If OP wanted to enforce a phone number cannot belong to both a Dude and a Business
- The inescapable feeling of sadness as a result of defining the relationship on the PhoneNumber model and not on the Dude/Business models. When extra terrestrials come to Earth, and we want to add an Alien model, we need to modify the PhoneNumber (assuming the ETs have phone numbers) instead of simply adding a “phone_numbers” field to the Alien model.
Introduce the content types framework, which exposes some objects that allow us to create a “generic foreign key” on the PhoneNumber model. Then, we can define the reverse relationship on Dude and Business
from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation
from django.contrib.contenttypes.models import ContentType
from django.db import models
class PhoneNumber(models.Model):
number = models.CharField()
content_type = models.ForeignKey(ContentType, on_delete=models.CASCADE)
object_id = models.PositiveIntegerField()
owner = GenericForeignKey()
class Dude(models.Model):
numbers = GenericRelation(PhoneNumber)
class Business(models.Model):
numbers = GenericRelation(PhoneNumber)
See the docs for details, and perhaps check out this article for a quick tutorial.
Also, here is an article that argues against the use of Generic FKs.
- [Django]-How to obtain and/or save the queryset criteria to the DB?
- [Django]-How can I see the raw SQL queries Django is running?
- [Django]-Using django-admin on windows powershell
4👍
First of all we take a tour:
01) one-to-many relationship:
ASSUME:
class Business(models.Model):
name = models.CharField(max_length=200)
.........
.........
phone_number = models.OneToMany(PhoneNumber) (NB: Django do not support OneToMany relationship)
class Dude(models.Model):
name = models.CharField(max_length=200)
.........
.........
phone_number = models.OneToMany(PhoneNumber) (NB: Django do not support OneToMany relationship)
class PhoneNumber(models.Model):
number = models.CharField(max_length=20)
........
........
NB: Django doesn’t provides any OneToMany relationship. So we can’t use upper method in Django. But we need to convert in relational model. So what can we do? In this situation we need to convert relational model into reverse relational model.
Here:
relational model = OneToMany
So, reverse relational model = ManyToOne
NB: Django support ManyToOne relationship & in Django ManyToOne is represented by ForeignKey.
02) many-to-one relationship:
SOLVE:
class Business(models.Model):
.........
.........
class Dude(models.Model):
.........
.........
class PhoneNumber(models.Model):
........
........
business = models.ForeignKey(Business)
dude = models.ForeignKey(Dude)
NB: THINK SIMPLY!!
- [Django]-Django admin default filter
- [Django]-Do django db_index migrations run concurrently?
- [Django]-Python Socket.IO client for sending broadcast messages to TornadIO2 server
3👍
Actually, one-to-many relationship is very useful. I do something like this:
class Dude(models.Model):
number = models.ManyToManyField(PhoneNumber)
def save(self, *args, **kwargs):
if Dude.objects.get(number=self.number):
raise Exception("Dude, this number has been used.")
return super(Dude, self).save(*args, **kwargs)
class PhoneNumber(models.Model):
number = models.CharField(...)
This will ensure the number only use once.
- [Django]-Is there a list of Pytz Timezones?
- [Django]-Django custom field validator vs. clean
- [Django]-Python (and Django) best import practices
1👍
Whereas most answers here do pass in defining a relationship that allows you to define a OneToManyRelationship, they are actually in fact the definition of a ManyToManyRelationship.
Here is a more accurate implementation:
class Dude(models.Model):
name = models.CharField(max_length=256, unique=True)
class PhoneNumber(models.Model):
number = models.CharField(max_length=256, unique=True)
class DudePhoneNumbers(models.Model):
dude = models.ForeignKey(Dude, related_name="phone_number_relations", on_delete=models.CASCADE)
phone_number = models.OneToOneField(PhoneNumber, related_name="dude_relation", on_delete=models.CASCADE)
- [Django]-In a Django form, how do I make a field readonly (or disabled) so that it cannot be edited?
- [Django]-How do I make many-to-many field optional in Django?
- [Django]-Python Asyncio in Django View
0👍
If the “many” model does not justify the creation of a model per-se (not the case here, but it might benefits other people), another alternative would be to rely on specific PostgreSQL data types, via the Django Contrib package
Postgres can deal with Array or JSON data types, and this may be a nice workaround to handle One-To-Many when the many-ies can only be tied to a single entity of the one.
Postgres allows you to access single elements of the array, which means that queries can be really fast, and avoid application-level overheads. And of course, Django implements a cool API to leverage this feature.
It obviously has the disadvantage of not being portable to others database backend, but I thougt it still worth mentionning.
Hope it may help some people looking for ideas.
- [Django]-Django models avoid duplicates
- [Django]-Django substr / substring in templates
- [Django]-Malformed Packet: Django admin nested form can't submit, connection was reset
0👍
A one to many relationship implies that one model record can have many other model records associated with itself.
from django.db import models
class Menu(models.Model):
name = models.CharField(max_length=30)
class Item(models.Model):
menu = models.ForeignKey(Menu)
name = models.CharField(max_length=30)
description = models.CharField(max_length=100)
- [Django]-"<Message: title>" needs to have a value for field "id" before this many-to-many relationship can be used.
- [Django]-How to add a cancel button to DeleteView in django
- [Django]-How to upload a file in Django?