작업에 컨텐츠 유형 프레임 워크를 사용 하시겠습니까?
"이 모델들 중 어떤 모델이 다른 모델과 같은 방식으로 관련되어야합니까? 우리가이 질문을하는 이유는 이것이 콘텐츠 유형 프레임 워크가 가장 잘하는 것이기 때문입니다. 모델간에 일반적인 관계를 만듭니다. Blah blah, 몇 가지 코드를 살펴보고 무슨 뜻인지 봅시다.
# ourapp.models
from django.conf import settings
from django.db import models
# Assign the User model in case it has been "swapped"
User = settings.AUTH_USER_MODEL
# Create your models here
class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
slug = models.SlugField(unique=True)
body = models.TextField(blank=True)
class Picture(models.Model):
author = models.ForeignKey(User)
image = models.ImageField()
caption = models.TextField(blank=True)
class Comment(models.Model):
author = models.ForeignKey(User)
body = models.TextField(blank=True)
post = models.ForeignKey(Post)
picture = models.ForeignKey(Picture)
자, 우리는 이론적으로이 관계를 만들 수있는 방법이 있습니다. 그러나 파이썬 프로그래머로서, 당신의 뛰어난 지능은 이것이 짜증나고 더 잘 할 수 있다고 말하고 있습니다. 하이 파이브!
컨텐츠 유형 프레임 워크를 입력하십시오!
자, 이제 우리는 모델을 자세히 살펴보고보다 "재사용 가능하고"직관적 인 모델로 재 작업 할 것입니다. 우리의 외래 키 두 개를 제거하여 시작합시다.Comment
모델 하고로 대체 해GenericForeignKey
.
# ourapp.models
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
...
class Comment(models.Model):
author = models.ForeignKey(User)
body = models.TextField(blank=True)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = GenericForeignKey()
그래서 무슨 일이야? 글쎄, 우리는 다른 모델과의 일반적인 관계를 위해 필요한 코드를 추가하고 추가했습니다. 공지 단지보다이 방법 GenericForeignKey
도 있지만,이 ForeignKey
에 ContentType
와 PositiveIntegerField
에 대한이 object_id
. 이 필드들은 장고에게 어떤 종류의 객체와 관련이 있고 그 객체의 id가 무엇인지 알려주기위한 것입니다. 실제로 Django는 이러한 관련 객체를 조회해야하기 때문에 이것이 의미가 있습니다.
글쎄, 그것은 파이썬과 같지 않습니다 ... 그것의 추악한!
귀도 반 로섬을 자랑스럽게 만들 수있는 완벽한 밀폐형의 직관적 인 코드를 찾고있을 것입니다 . 당신을 얻습니다. GenericRelation
우리가 이것에 예쁜 활을 넣을 수 있도록 들판을 보자 .
# ourapp.models
from django.contrib.contenttypes.fields import GenericRelation
...
class Post(models.Model):
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
slug = models.SlugField(unique=True)
body = models.TextField(blank=True)
comments = GenericRelation('Comment')
class Picture(models.Model):
author = models.ForeignKey(User)
image = models.ImageField()
caption = models.TextField(blank=True)
comments = GenericRelation('Comment')
밤! 이와 같이이 두 모델에 대한 주석으로 작업 할 수 있습니다. 사실, 쉘 python manage.py shell
에서 Django 프로젝트 디렉토리에서 입력 하십시오.
>>> from django.contrib.auth import get_user_model
>>> from ourapp.models import Picture, Post
# We use get_user_model() since we are referencing directly
User = get_user_model()
# Grab our own User object
>>> me = User.objects.get(username='myusername')
# Grab the first of our own pictures so we can comment on it
>>> pic = Picture.objects.get(author=me)
# Let's start making a comment for our own picture
>>> pic.comments.create(author=me, body="Man, I'm cool!")
# Let's go ahead and retrieve the comments for this picture now
>>> pic.comments.all()
[<Comment: "Man, I'm cool!">]
# Same for Post comments
>>> post = Post.objects.get(author=me)
>>> post.comments.create(author=me, body="So easy to comment now!")
>>> post.comments.all()
[<Comment: "So easy to comment now!"]
그렇게 간단합니다.
이러한 "일반적인"관계의 다른 실질적인 영향은 무엇입니까?
일반적인 외래 키를 사용하면 다양한 응용 프로그램간에 덜 관입적인 관계를 유지할 수 있습니다. 예를 들어, Comment 모델을 이름이 인 자체 앱으로 가져 왔다고 가정 해 봅시다 chatterly
. 이제 noise_nimbus
사람들이 음악을 저장하여 다른 사람들과 공유 할 수있는 다른 응용 프로그램을 만들고 싶습니다 .
노래에 댓글을 추가하려면 어떻게해야합니까? 우리는 일반적인 관계를 그릴 수 있습니다.
# noise_nimbus.models
from django.conf import settings
from django.contrib.contenttypes.fields import GenericRelation
from django.db import models
from chatterly.models import Comment
# For a third time, we take the time to ensure custom Auth isn't overlooked
User = settings.AUTH_USER_MODEL
# Create your models here
class Song(models.Model):
'''
A song which can be commented on.
'''
file = models.FileField()
author = models.ForeignKey(User)
title = models.CharField(max_length=75)
slug = models.SlugField(unique=True)
description = models.TextField(blank=True)
comments = GenericRelation(Comment)
나는 당신이 나에게 더 현실적인 적용 GenericForeignKey
과 GenericRelation
분야 를 보여 주었던 것을 발견하고 싶었을 때 이것이 도움이 되길 바랍니다 .
이것이 사실이 너무 좋은가요?
인생의 모든 것과 마찬가지로 장단점이 있습니다. 더 많은 코드와 추상화를 추가 할 때마다 기본 프로세스가 더 무겁고 느려집니다. 일반 관계를 추가하면 결과를 스마트 캐시하고 시도하더라도 사실에 약간의 성능 저하가 추가 될 수 있습니다. 대체로 청결성과 단순성이 작은 성능 비용을 능가하는지 여부가 결정됩니다. 나에게 답은 백만 배입니다.
여기에 표시 한 것보다 더 많은 컨텐츠 유형 프레임 워크가 있습니다. 세밀한 수준과 자세한 사용법이 있지만 평균 개인의 경우 내 의견으로는 10 번 중 9 번 사용하는 방법입니다.
일반적인 관계자 (?)에주의하십시오!
다소 큰 경고 는을 사용할 때 적용된 ( )이 GenericRelation
있는 모델 이 삭제되면 모든 관련 ( ) 객체도 삭제된다는 것입니다. 또는 적어도이 글을 쓰는 시점에서.GenericRelation
Picture
Comment