데이터베이스 테이블에서 Foreign Key(이하 FK)가 없고 다른테이블의 FK로 지정된 테이블일때, 나를 참조하는(나를 FK로 지정한) 테이블에 접근하는 것
# 유저목록 테이블, 사용자이름과 비밀번호 저장한다.
class User(models.Model):
# PK, unique, AI 자동생성
# 직접 지정 : id = models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)
user_name = models.CharField(max_length=50)
password = models.CharField(max_length=200)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
# 지금 User테이블에서 userprofile이 역참조 되고 있다. 사용하기 불편쓰!!..
# User가 Userprofile을 정참조하는것이 데이터 접근 이 용이하다.. 코드도 쉽공
class Meta:
db_table = 'users'
# 유저의 사진과, 자기소개 글이 등록된 테이블 유저테이블의 1:1관계
class UserProfile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='user_uniq_id')
# ! related_name은 역참조시 사용, 지정하지 않으면 기본 역참조는 테이블명소문자_set으로 역참조를 찾아간다.
image_url = models.CharField(max_length=300, null=True)
description = models.CharField(max_length=100, null=True)
create_at = models.DateTimeField(auto_now_add=True)
update_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'user_profile'
# 인스타그램 피드 테이블, 유저의 이름, 프로필사진, 댓글 정보를 외부에서 가져와야 한다.
class Feed(models.Model):
user = models.ForeignKey('account.User', on_delete = models.CASCADE, related_name = 'author')
# ? user, user_profile이 1:1일때 굳이 user_profile컬럼을 추가할 필요없다..!
# user_profile = models.ForeignKey('account.UserProfile', on_delete = models.SET_NULL, null = True, related_name = 'avatar')
image_url = models.CharField(max_length = 300, verbose_name = 'image')
content = models.TextField(verbose_name = 'content')
like = models.IntegerField(verbose_name = 'likes', null = True)
create_at = models.DateTimeField(auto_now_add = True)
update_at = models.DateTimeField(auto_now = True)
comment = models.ManyToManyField('Comment', through = 'FeedComment', related_name = 'feed_comment')
feed = models.ManyToManyField('Feed', through = 'FeedComment', related_name = 'comment_feed')
class Meta:
db_table = 'feeds'
위 DB모델 구조는 User와 UserProfile의 참조방향이 잘못되어 있어 테이블에 접근방식이 복잡해졌다. (User테이블에 FK로 UserProfile을 두었으면 편한뎅..) 하지만 접근 할 수는 있기 때문에 그 방법을 알아보자!
# 테이블에 related_name이 없이 역참조 되었을때
>>> feed.user.userprofile_set.all()
>>> feed.user.userprofile_set.filter(user_id=feed.user.id)[0].image_url
# 유저 프로필 사진url이 출력된다.
# 테이블에 related_name이 지정되었을 경우
# 위 _set 방식과 동일한 결과를 출력한다.
>>> feed.user.user_uniq_id.all()
>>> feed.user.user_uniq_id.filter(user_id=feed.user.id)[0].image_url
<QuerySet [num]>
을 리턴하기 때문에 인덱싱을 먼저 한뒤 객체 내용을 검색 할 수 있다.<QuerySet Object>
를 리턴한다.