python/Django
[Django] ORM - 1:N 관계 (ForeignKey) (일대다관계 1)
http://portfolio.wonpaper.net
2022. 5. 14. 09:50
Django 에서 Model 간의 관계에 관해 몇가지 정리해 본다.
User 와 Album 모델은 Album.owner FoeignKey 로 연결되어 있다.
1
2
3
4
5
6
|
from django.contrib.auth.models import User
class Album(models.Model):
name = models.CharField('NAME', max_length=30)
description = models.CharField('One Line Description', max_length=100, blank=True)
owner = models.ForeignKey('auth.User', on_delete=models.CASCADE, verbose_name='OWNER', blank=True, null=True)
|
cs |
[ 1:N ]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
>>> from django.contrib.auth.models import User
>>> from photo.models import Album
# User 테이블의 모든 레코드를 확인
>>> User.objects.all()
<QuerySet [<User: shkim>, <User: guest>]>
# Album 테이블의 모든 레코드를 확인
>>> Album.objects.all()
<QuerySet [<Album: Django>, <Album: Nature>, <Album: 국가별>, <Album: 사람들>]>
# 특정한 앨범 객체 하나를 조회하고 그 소유자 확인한다.
>>> a2 = Album.objects.All()[2]
>>> a2
<Album: 국가별>
>>> a2.owner
<User: shkim>
#앨범 객체를 통해 사용자 객체의 username 필드를 통해 사용자이름을 확인
>>> a2.owner.username
'shkim'
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
# 사용자 객체를 조회해 u1, u2객체에 대입
>>> u1 = User.objects.get(username='shkim')
>>> u2 = User.objects.get(username='guest')
# 앨범을 새로 하나 만들고 앨범 소유자를 지정한다. - 2가지 방법
# [방법 1] 새로운 앨범 객체를 생성하고 save() 시키고, add() 시킨다.
>>> newa1 = Album(name='TestAlbum1')
>>> newa1
<Album: TestAlbum1>
>>> newa1.save()
>>> u1.album_set.add(newa1)
>>> u1.album_setl.all()
<QuerySet [<Album: TestAlbum1>, <Album: 국가별>]>
# [방법 2] 특정 사용자 객체에서 바로 create() 해서 새로운 앨범을 추가하면서, 그 사용자객체를 지정한다.
>>> newa2 = u2.album_set.create(name='TestAlbum2')
>>> newa2
<Album: TestAlbum2>
>>> u2.album_set.all()
[<Album: TestAlbum2>]
# 방금 만든 앨범 newa1의 소유자를 u1 -> u2 로 변경
>>> u2.album_set.add(newa1)
>>> newa1.owner
<User: guest>
>>> u2.album_set.all()
[<Album: TestAlbum1>, <Album: TestAlbum2>]
# 소유자가 u2인 앨범의 갯수
>>> u2.album_set.count()
2
>>> u1.album_set.all()
<QuerySet [<Album: 국가별>]>
# 모델 간 관계에서도 필드검색해 본다.
>>> u2.album_set.filter(name__startwidth='Test')
<QuerySet [<Album: TestAlbum1>, <Album: TestAlbum2>]>
>>> Album.objects.filter(owner__username='guest1')
<QuerySet [<Album: TestAlbum1>, <Album: TestAlbum2>]>
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
# 조건 2개 이상이면 AND 형태로
>>> Album.objects.filter(owner=u2, name__startswith='Test')
<QuerySet [<Album: TestAlbum1>, <Album: TestAlbum2>]>
# 앨범 모델에서 소유자를(소유자의 앨범을) 불러오는 여러가지 방법들
>>> Album.objects.filter(owner__pk=1)
<QuerySet [<Album: 국가별>]>
>>> Album.objects.filter(owner=1)
<QuerySet [<Album: 국가별>]>
>>> Album.objects.filter(owner=u1)
<QuerySet [<Album: 국가별>]>
>>> Album.objects.filter(owner__in=[1]).distinct()
<QuerySet [<Album: 국가별>]>
>>> Album.objects.filter(owner__in=[u1]).distinct()
<QuerySet [<Album: 국가별>]>
>>> Album.objects.filter(owner__in=User.objects.filter(username='shkim')).distinct()
<QuerySet [<Album: 국가별>]>
# User 모델에서 앨범을(앨범의 소유자를) 불러오는 여러가지 방법들
>>> User.objects.filter(album__pk=6)
<QuerySet [<User: shkim>]>
>>> User.objects.filter(album=6)
<QuerySet [<User: shkim>]>
>>> User.objects.filter(album=a2)
<QuerySet [<User: shkim>]>
# 필드 검색
>>> User.objects.filter(album__name__startswidth='Test')
<QuerySet [<User: guest>, <User: guest>]>
>>> User.objects.filter(album__name__startswidth='Test').distinct()
<QuerySet [<User: guest>]>
>>> User.objects.filter(album__name__startswidth='Test').distinct().count()
1
|
cs |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
# 순환방식으로 필드 검색
>>> User.objects.filter(album__owner=u1)
<QuerySet [<User: shkim>]>
>>> Album.objects.filter(owner__album=a2)
<QuerySet [<Album: 국가별>]>
# 1:N 관계에서 1 쪽의 객체를 지우면 CASCADE 로 인해 N 쪽의 객체도 같이 삭제된다.
>>> u3 = User.objects.create(username='guest3')
>>> u3.album_set.create(name='TestAlbum3')
<Album: TestAlbum3>
# 삭제 전, u3 소유의 앨범을 확인해본다.
>>> u3.album_set.all()
[<Album: TestAlbum3>]
# delete() 메소드는 삭제된 개수를 반환한다.
>>> u3.delete()
(2, {'admin.LogEntity': 0, 'auth.User_groups': 0, 'auth.User_user_permissions':0, 'bookmark.Bookmark': 0, 'photo.Photo': 0, 'auth.User': 1, 'photo.Album': 1})
# guest3 객체가 삭제된것을 확인해본다.
>>> User.objects.all()
<QuerySet [<User: shkim>, <User: guest>]>
# u3 소유의 TestAlbum3 앨범도 같이 삭제된것을 확인해본다.
>>> Album.objects.all()
<QuerySet [<Album: Django>, <Album: Nature>, <Album: TestAlbum1>, <Album: TestAlbum2>, <Album: 국가별>, <Album: 사람들>]>
|
cs |
참고 : [실전편] Django 를 활용한 쉽고 빠른 웹개발 파이썬 웹프로그래밍 (김석훈) , 설명예제