How do I express a Django ManyToMany relationship? - django

I'm hitting a wall here and I know this is a simple question, but I was unable to find it here.
In an ER diagram, what would the relationship be between two objects that have a ManyToMany relationship, in terms of the intermediary table?
Example:
item ---- item_facts ---- fact
I feel like it should be one to one but I'm not completely sure.

user --many2many-- group
user 1----n user_group n---1 group

In django documentation it states that
A many-to-many relationship. Requires a positional argument: the class to which the model is related. This works exactly the same as it does for ForeignKey, including all the options regarding recursive and lazy relationships.
Behind the scenes, Django creates an intermediary join table to represent the many-to-many relationship. By default, this table name is generated using the name of the many-to-many field and the model that contains it. Since some databases don't support table names above a certain length, these table names will be automatically truncated to 64 characters and a uniqueness hash will be used. This means you might see table names like author_books_9cdf4; this is perfectly normal. You can manually provide the name of the join table using the db_table option.
And ForeignKey definition is like:
A many-to-one relationship. Requires a positional argument: the class to which the model is related.
So,ManyToMany relations created by django are creating intermedıary tables that are 1 to N.

Not sure what the question is here. You say that the two objects have a many-to-many relationship.
If two objects (entitied, tables) have a many-to-many relationship, whether you include the intermediate table in the diagram or not, is irrelevant. They still have a many-to-many relationship.

Related

ManyToMany self-referenced with extra column in Doctrine

I have problem which is easy to solve with pure SQL but I need to solve it with Doctrine in YAML.
I have well known db tables users and friends. Where users table has primary key user_id and friends has friend_id and friend_with_id which uses user_id from table user. My problem starts when I need to add there one more column mood. With SQL I add to table friends onemore column named mood and it's done with doctrine I can't find any solution.
For better understanding I add db scheme:
I dont see any self-reference relationship here. Both friend_id and friend_with_id points to users.user_id. What I see is, two one-to-many relationships from the user side OR two many-to-one relationships from the friends side.
So, there will be two ArrayCollection objects (ManyToOne) in the Friend entity corresponding to friend_id and friends_with_id. Similarly two ArrayCollections (OneToMany) on the User entity, namely, myFriends and friendsWith.

django select_related for multiple foreign keys

How does select_related work with a model which has multiple foreign keys? Does it just choose the first one?
class Model:
fkey1, fkey2, fkey3...
The documentation doesn't say anything about this, at least not in where the method is specified.
NOTE: Maybe I'm the only one who will get confused. I guess select_related is just a performance booster (I can see that) but I had the wrong idea that it was something else.
You can use select_related in a chain as following
Comment.objects.select_related('user').select_related('article').all()
If your model has multiple foreign keys you can:
Call .select_related(), that will “follow” all non-null foreign-key relationships
Call .select_related('foreign_key1', 'foreign_key2', ...), that will “follow” only the foreign-key provided as arguments.
Note that "to follow a FK relationship" means selecting additional related-object data when the query is executed (by performing a SQL join). This will make the main query heavier but can be used to avoid N + 1 queries problem.
According to select_related documentation, the first method (without arguments) is not recommended as "it is likely to make the underlying query more complex, and return more data, than is actually needed."
If your model has "nested" foreign keys with other models (i.e. Book <>-- Author <>-- Hometown) you can also use select_related as follow:
Call Book.select_related('author__hometown'), that will “follow” the author's foreign-key (in Book model) and the hometown's foreign-key (in Author model).
If your model has many-to-many or many-to-one relations you would like to retrieve from the database, you should take a look at prefetch_related.
On the contrary, the documentation is very clear on the matter. It says that by default all ForeignKeys are followed, but you can give the method a list of fields and it will only follow those relationships.
You can pass foreign keys and even nested foreign keys to the select_related method eg select_related('book__author', 'publisher',) you can add as many foreign keys as you want, if you call select_related() without any argument then it will follow all the foreign key relationship which is not recommended at all because you'll be complicating the query by fetching data you don't need. Finally, from Django documentation "Chaining select_related calls works in a similar way to other methods - that is that select_related('foo', 'bar') is equivalent to select_related('foo').select_related('bar')

Web2py: id as foreign key

I am trying to implement some tables that mimic inheritance in a relational (sqlite) database. My goal is to have one master table with general fields, and some child tables with specialized fields. Every record in the master table will have exactly one counterpart in exactly one of the specific tables. What I want looks like this:
Master table:
id (PK) #Your average web2py unique auto-incrementing int field
#Some general fields
Child tables:
id (PK, FK referencing the PK of the master table)
#Some specialized fields
Having a default "id" PK for each child table has no use to me. All I need is an FK reference to the master table, which can serve as the PK for the child tables. This means that the PK of the child tables will be unique, but will contain gaps. This is because a child table will only reference some of the records of the master table.
I get the impression that doing this (not giving the child tables the regular "id" PK) is against the Web2py way. So my questions are as follows:
Is this a Bad Idea™? If so, why?
How would I implement this? Can Web2py handle tables that don't have an auto-incrementing int as PK?
It's very important for me to apply the correct style and practice when writing code. I am open to alternative approaches.
Thank you for your help.
See the book section on keyed tables. If this is a database specifically for use with web2py, I suggest you stick with the standard web2py approach:
db.define_table('master', ...)
db.define_table('child', Field('master', db.master))

One-to-many relation ship between 3 entities in Doctrine 2

I have three entities: User, Office and PhoneNumber. The user has many phone numbers, and the office has many phone numbers too.
The problem is how to represent these entities relations in Doctrine 2.
At first I tried to use bi-directional one-to-many associations
(User -> has many -> PhoneNumbers) (Office -> has many ->
PhoneNumbers), the PhoneNumber has two mapping fields, one for User
and anotherone for Office. This solution doesn't work since one of
the mapping foreign keys couldn't be null.
My second approach was to use two entities and one superclass for PhoneNumber. The PhoneNumber superclass has defined all common fields except the mapping field. Entities UserPhoneNumber and
OfficePhoneNumber extended the PhoneNumber entity and specified the
different mapping field and different table. (one table for OfficePhoneNumbers, anotherone for UserPhoneNumbers)
This solution actually works, but it is quite ugly to have 3
classes to represent one simple entity.
My third approach is to use uni-directional one-to-many mapping. This will eliminate the need of mapping field for the PhoneNumber entity. The problem is that when I use cascade remove for the many-to-many field, it violates the integrity constraint when deleting records.
When I omit the cascade remove option, after removing User or Office, the PhoneNumber remains in the Database (but the record in mapping table is removed).
What is the best way to handle this type of association?
Thanks
I finally solve the problem connected with (probably the nicest) solution 1). The problem was in misunderstanding of mappedBy attribute which should specify the entity field, not the database field.

unidirectional one-to-many and many-to-may in django

I'm new to django.
I have 2 simple objects, lets call them - File and FileGroup:
- A FileGroup can hold a list of files, sorted according to an 'order' field.
- Each file can be associated with multiple groups.
so basically, the db tables would be:
1) File
2) File_Group
3) File_Group_Mapping table that has a column named "order" in addition to the fk to the file and file group.
There is a many-to-many relationship here, but the File object is not supposed to be aware of the existence of the FileGroup (doesn't make sense in my case)
My questions -
Is there a way to create a unidirectional many-to-many/one-to-many relationship here? How can I model it with django?
I couldn't find a way to make it unidirectional via django.
I saw a solution that uses something like -
class FileGroup(...):
files = models.ManyToManyField(File, through='FileGroupMapping')
but this will make the File object aware of the FileGroup.
I can also do this via mapping the File_Group_Mapping table in the models file like this -
class FileGroupMapping(...):
files = models.ForeignKey(File)
groups = models.ForeignKey(FileGroup)
order = models...
What is the best way to do this via django?
Thanks
I am also much of a hibernate user. I totally understand what you are looking for, just try using the attribute "symmetrical = False" in your many to many relation ship this would make the relationship unidirectional.
class FileGroup(models.Model):
files = models.ManyToManyField(File, symmetrical = False)
This should do the trick!
Your two approaches are identical. Behind the scenes, Django creates a lookup table for a ManyToManyField. From the ORM perspective, you can put the ManyToManyField on either model, although it makes a difference in the admin, and if you wish to use the 'limit_choices_to' option. Using 'through' lets you add columns to the lookup table to further define the relationship between the two models, which is exactly what you've done by manually creating the lookup table.
Either way, you can still 'get' the FileGroup that a particular File belongs to, as Django querysets will follow a FK relationship bidirectionally.