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
signalsexcessively
celerydjango-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.)