[python] Django 컨텐츠 유형은 정확히 어떻게 작동합니까?

Django의 콘텐츠 유형 개념을 파악하는 데 어려움을 겪고 있습니다. 그것은 매우 해킹 감을 느끼고 궁극적으로 파이썬이 일을하는 방식에 반합니다. Django를 사용하려면 프레임 워크의 범위 내에서 작업해야합니다.

그래서 나는 누군가가 컨텐츠 유형의 작동 방식과 구현 방법에 대한 실제적인 예를 제시 할 수 있는지 궁금합니다. 필자가 검토 한 거의 모든 자습서 (주로 블로그)는 실제로 개념을 다루는 데 큰 도움이되지 않습니다. 그들은 Django 문서가 사라진 곳에서 픽업하는 것처럼 보입니다 (어딘가처럼 보입니다).



답변

작업에 컨텐츠 유형 프레임 워크를 사용 하시겠습니까?

“이 모델들 중 어떤 모델이 다른 모델과 같은 방식으로 관련되어야합니까? 우리가이 질문을하는 이유는 이것이 콘텐츠 유형 프레임 워크가 가장 잘하는 것이기 때문입니다. 모델간에 일반적인 관계를 만듭니다. 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도 있지만,이 ForeignKeyContentTypePositiveIntegerField에 대한이 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)

나는 당신이 나에게 더 현실적인 적용 GenericForeignKeyGenericRelation분야 를 보여 주었던 것을 발견하고 싶었을 때 이것이 도움이 되길 바랍니다 .

이것이 사실이 너무 좋은가요?

인생의 모든 것과 마찬가지로 장단점이 있습니다. 더 많은 코드와 추상화를 추가 할 때마다 기본 프로세스가 더 무겁고 느려집니다. 일반 관계를 추가하면 결과를 스마트 캐시하고 시도하더라도 사실에 약간의 성능 저하가 추가 될 수 있습니다. 대체로 청결성과 단순성이 작은 성능 비용을 능가하는지 여부가 결정됩니다. 나에게 답은 백만 배입니다.

여기에 표시 한 것보다 더 많은 컨텐츠 유형 프레임 워크가 있습니다. 세밀한 수준과 자세한 사용법이 있지만 평균 개인의 경우 내 의견으로는 10 번 중 9 번 사용하는 방법입니다.

일반적인 관계자 (?)에주의하십시오!

다소 큰 경고 는을 사용할 때 적용된 ( )이 GenericRelation있는 모델 이 삭제되면 모든 관련 ( ) 객체도 삭제된다는 것입니다. 또는 적어도이 글을 쓰는 시점에서.GenericRelationPictureComment


답변

질문에 대한 직접적인 대답은 다음과 같습니다. (django 소스 코드에서) 다음은
RFC 2616 섹션 3.7에 따라 구문 분석되는 미디어 유형입니다.

그것은 ‘Content- type’httpd 헤더 를 따라 읽거나 수정하고 / 전달한다는 것을 말하는 눈물 입니다.

그러나 더 많은 사용 사례를 요구하고 있습니다. 두 가지 제안이 있습니다.

1 :이 코드를 검사

def index(request):
   media_type='text/html'
   if request.META.has_key('CONTENT_TYPE'):
      media_type = request.META['CONTENT_TYPE'].split(';')[0]

   if media_type.lower() == 'application/json':
      return HttpResponse("""{ "ResponseCode": "Success"}""", content_type="application/json; charset=UTF-8")

   return HttpResponse("<h1>regular old joe</h1>");

2 : 장고는 파이썬이라는 것을 기억하십시오. 따라서 파이썬 커뮤니티의 힘을 발휘합니다. django에 2 개의 멋진 RESTFul 플러그인이 있습니다. 따라서 토끼 전체가 얼마나 깊이 들어가는 지 확인하려면 체크 아웃하십시오.

나는 django-rest-framework tutorial을 통해 ‘다른 내용 / 유형에 대한 행동’을 구체적으로 다루는 것이 좋습니다. 참고 : content-type 헤더를 사용하여 restful API‘version’ 하는 것이 일반적 입니다.


답변