relationships in django orm
TRANSCRIPT
Relationships in Django ORM@starwilly
Outline
• Single model ( Django girls tutorial )
• Relationship
• 1. many-to-one ( )
• 2. many-to-many (Tag)
• What does it looks like in database
• How to define relationship
• Traverse / query / create / delete relation
A Simple Django Model
CRUD (Create, Read, Update, Delete)
Post.objects.create(title='My First Trip', content=‘ ?', location=' ')
Post.objects.all()
[<Post: My First Trip>, <Post: My Second Trip>, <Post: Django >]
Post.objects.filter(pk__gt=1)
[<Post: My Second Trip>, <Post: Django >]
CRUD
posts = Post.objects.filter(pk__lt=3)
[<Post: My First Trip>, <Post: My Second Trip>]
posts.update(location=‘ ')
2
posts.delete()
Model : Table
id title content photo location created_at1 …2 …
Relationship
• many-to-one
• many-to-many
Many-to-one Relationship
•
•
• 1.
• 2.
Alan:
Bob:
Cindy:
Model
Many-to-one Relationship
•
PostComment
•
1m
ForeignKey
• (many-to-one)
ForeignKey(othermodel, **options)
Use Foreign Key to Define m:1
Comment Post
id author content1 Alan …2 Bob …3 Cindy …4 Denny5
id title content1 …2 …
id post_id author content1 1 Alan …2 1 Bob …3 1 Cindy …4 2 Denny5 2 Alan
id title content1 …2 …
Query m:1 Relationship
id = 1
Alan:
Bob:
Cindy:
Traverse many-to-one relationship
id (pk) = 1post1 = Post.objects.get(pk=1)
comments = Comment.objects.filter(post_id=1)
comments = Comment.objects.filter(post=post1)
[<Comment: Alan: >, <Comment: Bob: >, <Comment: Cindy: >]
Traverse many-to-one relationship
id (pk) = 1post1 = Post.objects.get(pk=1)
comments = post1.comment_set.all()
<Model>_set
[<Comment: Alan: >, <Comment: Bob: >, <Comment: Cindy: >]
Associate Post and Comment
post = Post.objects.get(pk=1)
comment = Comment(author=‘Billy’, content=‘hi’)
post.comment_set.add(comment)
Remove Comment from Post
post1 = Post.objects.get(pk=1)post1.comment_set.all()
[<Comment: Alan: >, <Comment: Bob: >, <Comment: Cindy: >]
c = Comment.objects.get(pk=1)
<Comment: Alan: >
c.delete()
post.comment_set.all()
[<Comment: Bob: >, <Comment: Cindy: >]
ForeignKey.related_name
comment_list = post.comment_set.all()
comment_list = post.comments.all()
Foreign Key
• (many-to-one relationship)
• <model>_set
• related_name
• add()
Many-to-many Relationships
Tag
myblog.com/post/1
myblog.com/tag/food
What is Many-to-many Relationship
Post Tag
• tag
• tag
n m
Tag Model
SlugField
• CharField
• (hyphen)
• • myblog.com/tags/ (X)
• myblog.com/tags/food (O)
• myblog.com/posts/[ ] (X)
• myblog.com/posts/a-wonderful-trip-in-japan (O)
Tag Table
id name slug1 food2 japan3 taiwan-north4 taipei
… …taipei
id title content1 …2 …
Post
Tag
, ,
id name slug1 food2 japan3 taiwan-north4 taipei
… …
id title content tags1 … 1, 3, 42 … 2
Post
Tag
, ,
id name slug1 food2 japan3 taiwan-north4 taipei
… …
id title content1 …2 …
Post
Tag
, ,
id name slug1 food2 japan3 taiwan-north4 taipei
… …
id post_id tag_id1 1 12 2 23 1 34 1 4
ManyToManyField
ManyToManyField(othermodel, **options)
tags = models.ManyToManyField('Tag', blank=True)
ManyToManyField
•
• Django m2m
ManyToManyField(othermodel, **options)
id title content1 …2 …
id name slug1 food2 japan… … …
id post_id tag_id1 1 12 2 23 1 34 1 4
Query M2M Relationship
from trips.models import Post, Tag
post1 = Post.objects.get(pk=1)
<Post: >
post1.tags.all()
[<Tag: >, <Tag: >]
Query M2M Relationship
from trips.models import Post, Tag
tag_food = Tag.objects.get(pk=1)
<Tag: >
tag_food.post_set.all()
[<Post: >]
ManyToManyField.related_name
tag_food = Tag.objects.get(pk=1)
tag_food.post_set.all()
tag_food.posts.all()
Create M2M Relationship
from trips.models import Post, Tag
post1 = Post.objects.get(pk=1)
tag_japan = Tag.objects.create(name=‘ ’, slug=‘japan’)
tag_food = Tag.objects.get(slug=‘food’)
post1.tags.add(tag_japan)
tag_food.post_set.add(post1)
Remove M2M Relationship
from trips.models import Post, Tag
tag_japan = Tag.objects.get(slug=‘japan’)
post1 = Post.objects.get(pk=1)
post1.tags.remove(tag_japan)
tag_japan.post_set.remove(post1)
Filter M2M Relationshipfrom trips.models import Post, Tag
tag_japan = Tag.objects.get(slug=‘japan’)tag_food = Tag.objects.get(slug=‘food’)
tag_japan.post_set.all()
# [<Post: >]
Post.objects.filter(tags=tag_japan)
# [<Post: >]
Post.objects.filter(tags__in=[tag_japan, tag_food])
#[<Post: >, <Post: >]
ManyToManyField
•
• Table (Mapping)
• releated_name
• add() , remove()
• https://docs.djangoproject.com/en/1.9/ref/models/relations/
Get your hand dirty
• Tag
• Tag
•
• Tag
• Tag Tag
Tips:
djangogirls/mysite/templates/post.html
Tips: Tag
djangogirls/mysite/templates/post.html
Tips: Tag
url(r'^tag/(?P<slug>[\w-]+)/$', tag_detail, name='tag_detail'),
djangogirls/mysite/trips/views.py
djangogirls/mysite/templates/tag.html