Relationships in Django ORM

Post on 21-Jan-2018

415 views 0 download

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