User:Andre Castro/2/django/manytomany: Difference between revisions

From XPUB & Lens-Based wiki
No edit summary
 
Line 70: Line 70:
==Working with many-to-many intermediary models==
==Working with many-to-many intermediary models==
When you specify an intermediary model using the through argument to a ManyToManyField, the admin will not display a widget by default. If we want to edit that information it can be done in the '''admin.py''' by using  admin.TabularInline
When you specify an intermediary model using the through argument to a ManyToManyField, the admin will not display a widget by default. If we want to edit that information it can be done in the '''admin.py''' by using  admin.TabularInline
http://charlesleifer.com/blog/self-referencing-many-many-through/


<pre>
<pre>

Latest revision as of 19:55, 18 January 2013

I want to introduce a character model to the database of spam email messages I have been developing.

This will be a way to account for the characters in the spam narratives, either the ones described in them or narrating them.

The character Model

In the character's model I must contain the following fields:

  • Name - CharField(max_length=200, unique=True)
  • Spam Messages - models.ManyToManyField(spam_msg)
  • Date of Birth - DateField(blank=True)
  • Date of Death - DateField(blank=True)
  • Nationality - CharField(blank=True, max_length=200)
  • Occupation - CharField(blank=True, max_length=200)
  • Biography - TextField(blank=True)
  • Appearances in media - TextField(blank=True)
  • Other - TextField(blank=True)
  • Picture file - ImageField/FileField/FilePathField (blank=True) http://stackoverflow.com/questions/5871730/need-a-minimal-django-file-upload-example
  • Rating

ManyToMany Relationship

ManyToManyField class ManyToManyField(othermodel[, **options])¶

A many-to-many relationship, requires a positional argument: the class to which the model is related. eg: Mr.Castro is relatated to spam_msg id=40, id=44

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 name of the table for the model that contains it.

many_to_many.gif


Relationship Data

Django allows you to specify the model that will be used to govern the many-to-many relationship. You can then put extra fields on the intermediate model. The intermediate model is associated with the ManyToManyField using the through argument to point to the model that will act as an intermediary. And because we want to associate data with the relationship between 2 models (eg: under what name a character appear in a spam message) We will use it. (See example in page)
https://docs.djangoproject.com/en/1.3/topics/db/models/#intermediary-manytomany

When you set up the intermediary model, you explicitly specify foreign keys to the models that are involved in the ManyToMany relation. This explicit declaration defines how the two models are related.


ManyToManyField.through

The most common use for this option is when you want to associate extra data with a many-to-many relationship.

Django will automatically generate a table to manage many-to-many relationships. However, if you want to manually specify the intermediary table, you can use the through option to specify the Django model that represents the intermediate table that you want to use.


Intermediate Model

When you set up the intermediary model, you explicitly specify foreign keys to the models that are involved in the ManyToMany relation. This explicit declaration defines how the two models are related.

  • it must contain only one foreign key to the target model
  • it must contain only one foreign key to the source model
  • Exception: when model has a many-to-many relationship to itself, through an intermediary model. In this case, 2 foreign keys to the same model are permitted, but they will be treated as the two (different) sides of the many-to-many relation.
  • When defining a many-to-many relationship from a model to itself, using an intermediary model, you must use symmetrical=False (see the model field reference).


ManyToMany(self): Relationships between characters

Eg:

Character A -- client-manager -- Character B
Character A -- business partner -- Character X
Character C -- lovers -- Character D

This is a reference to objects withing the same table/model. The relationship table must specified what is the affiliation between the 2 characters

http://stackoverflow.com/questions/11721157/django-many-to-many-m2m-relation-to-same-model


In the relationship table it has to indicated what is the 2 characters' afilitation

  • be ManyToMany: a character can be present in more that one email; one email can have more than one character.
  • the LINK TABLE must allow for the misspellings of the character's name (eg: Mr. Castro was spelled Mr. Costro in email#40)


Working with many-to-many intermediary models

When you specify an intermediary model using the through argument to a ManyToManyField, the admin will not display a widget by default. If we want to edit that information it can be done in the admin.py by using admin.TabularInline

http://charlesleifer.com/blog/self-referencing-many-many-through/

class MembershipInline(admin.TabularInline):
    model = Membership
    extra = 2

and indicating the interrelational model in the inlines of the 2 models that are connected through it!

class PersonAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)

class GroupAdmin(admin.ModelAdmin):
    inlines = (MembershipInline,)


Lastly the 2 models must be resgitered

admin.site.register(Person, PersonAdmin)
admin.site.register(Group, GroupAdmin)