Django 모델 역모드
Django를 사용할 때, 우리는 이 작업을 완성하는 코드를 작성하지만, 일부 코드는 우리가 모르는 과도한 계산이나 조작을 실행할 수 있습니다.이러한 작업은 실제 작업에서 유효하지 않거나 정반대일 수 있습니다.
여기서 저는 Django 모델 중의 일부 반모드를 언급할 것입니다.
A. Using
len(queryset)
instead ofqueryset.count()
len(queryset)
는 파이톤 해석기를 통해 응용 프로그램 단계에서 데이터베이스 기록 계수를 실행한다.이 점을 하려면 먼저 데이터베이스에서 모든 기록을 추출해야 한다. 이것은 계산량이 매우 큰 조작이다.그러나
queryset.count()
데이터베이스 단계에서 계수를 계산하고 계수만 되돌려줍니다.Post
:from django.db import models
class Post(models.Model):
author = models.CharField(max_length=100)
title = models.CharField(max_length=200)
content = models.TextField()
만약 우리가 len(queryset)
를 사용한다면, 이것은 SELECT * FROM post
처럼 계산을 처리하고, 기록 목록 (queryset) 을 되돌려주고python 해석기가queryset의 길이를 계산합니다. 이것은 목록 데이터 구조와 유사합니다.많은 기록을 다운로드하는 것은 단지 길이를 검사하고 마지막에 버리기 위해서일 뿐이다. 얼마나 낭비하는가!그러나 우리가 읽는 길이를 기록해야 한다면 len(queryset)
유효할 수 있다.만약 우리가
queryset.count()
를 사용한다면 데이터베이스 단계에서 SELECT COUNT(*) FROM post
처럼 계산을 처리할 것이다.그것은 코드를 더욱 빨리 실행하고 데이터베이스 성능을 향상시켰다.B. Using
queryset.count()
instead ofqueryset.exists()
queryset.count()
를 사용한다고 칭찬해 왔지만,queryset의 존재를 검사하려면 사용하면 성능이 떨어질 수 있습니다.동일한 모델
Post
에 대해 작성자Arjun
가 쓴 댓글이 있는지 확인하고 싶을 때 다음과 같이 할 수 있습니다.posts_by_arjun: Queryset = Post.objects.filter(author__iexact='Arjun')
if posts_by_arjun.count() > 0:
print('Arjun writes posts here.')
else:
print('Arjun doesnt write posts here.)
posts_by_arjun.count()
데이터베이스 테이블의 각 행을 검색하는 SQL 작업을 수행합니다.그러나 If Arjun writes posts here or not ?
에만 관심이 있다면 보다 효율적인 코드는 다음과 같습니다.posts_by_arjun: Queryset = Post.objects.filter(author__iexact='Arjun')
if posts_by_arjun.exists():
print('Arjun writes posts here.')
else:
print('Arjun doesnt write posts here.)
posts_by_arjun.exists()
최소한 하나의 결과가 존재하는지 확인하는 브리 표현식을 되돌려줍니다.그것은 단지 가장 최적화된 방식으로 단일 기록을 읽을 뿐이다. (정렬 삭제, 사용자 정의 제거 select_related()
또는 distinct()
방법)또한queryset의 존재성/진실성을 이렇게 검사하는 것은 효과가 없다.
posts_by_arjun: Queryset = Post.objects.filter(author__iexact='Arjun')
if posts_by_arjun:
print('Arjun writes posts here.')
else:
print('Arjun doesnt write posts here.)
이는 아준의 게시물이 있는지 확인하는 데는 잘했지만, 더 많은 기록에 대해서는 계산량이 많았다.따라서 사용queryset.exists()
을 권장하여 조회집의 존재성/진실성을 검사한다.C. Using
signals
excessively
celery
django-debug-toolbar
은 추적 촉발 신호에 어느 정도 도움이 된다.Post
에 쓴 기록을 저장하고 싶은 장면을 만듭니다.class PostWritings(models.Model):
author = models.CharField(max_length=100, unique=True)
posts_written = models.PositiveIntegerField(default=0)
PostWritings
모델에 생성된 기록에 따라 자동으로 업데이트PostWritings
기록을 사용하려면 신호가 있거나 없는 상황에서 작업을 완성할 수 있는 몇 가지 방법이 있습니다.A.신호가 있다
from django.db.models.signals import post_save
from django.db.models import F
from django.dispatch import receiver
from .models import Post
@receiver(sender=Post, post_save)
def post_writing_handler(sender, instance, created, **kwargs):
if created:
writing, created = PostWritings.objects.get_or_create(author=instance.author)
writing.update(posts_written=F('posts_written') + 1)
B. 신호가 없어요.우리는
Post
모델을 덮어쓰는 save()
방법이 필요하다.from django.db import models
from django.db.models import F
class Post(models.Model):
author = models.CharField(max_length=100)
title = models.CharField(max_length=200)
content = models.TextField()
def save(self, *args, **kwargs:
# Overridden method.
author = self.author
if self.id:
writing, created = PostWritings.objects.get_or_create(author=author)
writing.update(posts_written=F('posts_written') + 1)
super(Post, self).save(*args, **kwargs)
같은 작업은 신호가 없는 상황에서 완성할 수 있기 때문에 코드는 불필요한 사건의 촉발을 쉽게 추적하고 방지할 수 있다.만약
Post
방법이 읽을 수 없다고 생각하는 사람이 있다면, 코드를 분해하는 것은 항상 좋다.우리 하자.from django.db import models
from django.db.models import F
class Post(models.Model):
author = models.CharField(max_length=100)
title = models.CharField(max_length=200)
content = models.TextField()
def _update_post_writing(self, created=False, author=None):
if author is not None and created:
writing, created = PostWritings.objects.get_or_create(author=author)
writing.update(posts_written=F('posts_written') + 1)
def save(self, *args, **kwargs:
# Overridden method.
author = self.author
created = self.id is None
super(Post, self).save(*args, **kwargs)
self._update_post_writing(created, author)
보아하니 우리는 Django 모델의 일부 반모드를 어떻게 완화하는지 배운 것 같다.지금 초대해 주셔서 감사합니다.나는 곧 더 많은 Django에 관한 이야기를 계속할 것이다.너도 GitHub에서 나를 찾을 수 있다.그 전
save()
Reference
이 문제에 관하여(Django 모델 역모드), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/thearjun/django-models-anti-patterns-1ma1텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)