Django 모델의 사용자 정의 요약
문에서 Book.objects.all()에서
objects
는 특수한 속성으로 데이터베이스를 조회하는데 그것이 바로 모델의 관리자이다.모든 Django 모델에는 최소한 하나의 관리자가 있습니다. 사용자 정의 관리자를 만들어서 데이터베이스에 접근할 수 있습니다.사용자 정의 관리자를 만드는 두 가지 방법이 있습니다: 추가 관리자를 추가합니다.관리자가 반환하는 초기 Queryset을 수정합니다.추가 관리자 추가
추가 관리자를 추가하는 것은 모듈에 표급 기능을 추가하는 최선의 방법이다.(행급 기능, 즉 모델 실례 대상에만 작용하는 함수는 사용자 정의 모델 방법을 통해 실현된다).예를 들어 Book 모형에
title_count()
의 manger 방법을 추가하면 keyword
를 수신하고 제목에 포함된 책의 수량을 되돌려줍니다.#medols.py
from django.db import models
class BookManager(models.Manager):
def title_count(self, keyword):
return self.filter(title_icountains=keyword).count()
class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
...
objects = BookManager()
def __str__(self):
return self.title
1. BookManager 클래스를 만듭니다
keyword
.그것은 단지 하나의 방법django.db.models.Manager
으로만 통계를 진행할 수 있다.주의, 이 방법은 title_count()
를 사용했는데, 이self는 관리자 자체를 가리킨다.2. 모델의 Objects 속성에 BookManager()의 값을 지정합니다.이것은 모델의 기본 관리자 (objects) 를 대체할 것입니다.기본 관리자와 일치하도록 Objects라고 명명합니다.이제 다음과 같은 작업을 수행할 수 있습니다.>>> Books.objects.title_count('django') # manager
2
>>> Books.objects.filter(title__icontains='django').count() #
2
이렇게 하면 우리는 자주 사용하는 조회를 봉인할 수 있으니 코드를 중복 쓸 필요가 없다.
초기 Manager Queryset 수정
관리자의 기본Queryset은 시스템의 모든 객체를 반환합니다.예를 들어
self.filter()
책 데이터베이스에 있는 모든 책을 되돌려줍니다.덮어쓰기 Book.objects.all()
방법으로 관리자의 기초Queryset을 다시 쓸 뿐입니다.Manager.get_queryset()
당신의 요구에 따라Queryset을 되돌려야 합니다.예를 들어 다음 모델에는 두 개의 manger가 있는데 하나는 모든 대상을 되돌려주고, 다른 하나는 작가가 Roald Dahl의 책만 되돌려준다.from django.db import models
# , Manager
class DahlBookManager(models.Manager):
def get_queryset(self):
return super(DahlBookManager, self).get_queryset().filter(author='Roald Dahl')
# , Book
class Book(models.Model):
title = models.CharField(max_length=100)
author = models.CharField(max_length=50)
...
objects = models.Manager() # Manager
dahl_objects = DahlBookManager() # Manager
이 예시 모델에서
get_queryset()
는 데이터베이스에 있는 모든 책을 되돌려주고Book.objects.all()
는 저자가 Roald Dahl인 책만 되돌려준다.우리가 이렇게 하지 않으면dahlobjects는 유일하게 사용할 수 있는 관리자가 될 것입니다.Book.dahl_objects.all()
Queryset 대상을 되돌려주기 때문에 objects
,get_queryset()
및 기타 모든Queryset 방법을 사용할 수 있습니다.사용자 정의 Manager 객체를 사용하는 경우 Django가 처음 만나는 Manager (모델에 정의된 위치를 기준으로 함) 는 특수한 상태를 가집니다.Django는 첫 번째 관리자를 기본 관리자로 정의합니다. Django의 많은 부분 (관리자 응용 프로그램은 포함되지 않음) 은 모델에 이 관리자를 명확하게 사용할 것입니다.결론은 기본 관리자를 조심스럽게 선택해야 한다는 것이다.덮어쓰기
filter()
때문에, 쓸모없는 반환 대상을 받아들일 수 있습니다. 이런 상황을 피해야 합니다.2. 모델 사용자화 방법
당신의 이미지에 줄 기능을 추가하기 위해서 사용자 정의 방법을 정의합니다.관리자가 시계 조작에 자주 사용되는 것을 감안하면 (table-wide)모형 방법은 특수 모형의 실례에만 작용해야 한다.
from django.db import models
class Person(models.Model):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
birth_date = models.DateField()
def baby_boomer_status(self):
# Returns the person's baby_boomer status
import datetime
if self.birth_date < datetime.date(1945, 8, 1):
return 'Pre-boomer'
elif self.birth_date < datetime.date(1965, 1, 1):
return 'Baby boomer'
else:
return 'Post-boomer'
def _get_full_name(self):
# Return the person's full name
return f'{self.first_name} {self.last_name}'
full_name = property(_get_full_name) #
이러한 방법의 사용:
>>> p = Person.objects.get(first_name='Barack', last_name='Obama')
>>> p.birth_date
datetime.date(1961, 8, 4)
>>> p.baby_boomer_status()
'Baby boomer'
>>> p.full_name # --
'Barack Obama'
3. 미리 정의된 모델을 다시 쓰는 방법
사용자 정의할 수 있는 데이터베이스 행동을 봉인하는 모형 방법도 있습니다.특히
exclude()
과get_queryset()
의 작업 방식을 수정하고 싶을 수도 있습니다.너는 이 방법들을 자유롭게 다시 써서 행동을 바꿀 수 있다.내장된 방법을 다시 쓰는 대표적인 예는 대상을 저장하고 다른 일을 하려는 것이다.예를 들면 다음과 같습니다.from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self, *args, **kwargs):
do_something()
super(Blog, self).save(*args, **kwargs) #Call the "real" save() method.
do_something_else()
저장 동작을 막을 수도 있습니다:
from django.db import models
class Blog(models.Model):
name = models.CharField(max_length=100)
tagline = models.TextField()
def save(self, *args, **kwargs):
if self.name == 'Yoko Ono's Blog':
return # Yoko shall never have her own blog!
else:
super(Blog, self).save(*args, **kwargs) #Call the "real" save() method
초클래스를 계승하는 방법은 매우 중요하다. 즉,
save()
이 대상이 데이터베이스에 저장될 수 있도록 확보하는 것이다.만약 당신이 클래스 초과 방법을 호출하는 것을 잊어버리면 기본 행위는 발생하지 않을 뿐만 아니라 데이터베이스 조작도 발생하지 않을 것이다.마찬가지로 모델 방법에 전달할 수 있는 매개 변수를 전달해야 한다. 이것이 바로 delete()
하는 일이다.Django는 내장된 모델 메서드의 기능을 수시로 확장하고 새 매개변수를 추가합니다.방법 정의에서 super(Blog, self).save(*args, **kwargs)
을 사용하면, 코드가 추가될 때 자동으로 이 인자들을 지원할 수 있습니다.Model.clean()
이 방법을 응용하여 사용자 정의 모델 검증과 모델의 속성을 수정합니다.예를 들어 한 필드에 값을 자동으로 제공하거나 여러 필드에서 함께 검증해야 하는 경우에 사용할 수 있습니다.
import detetime
from django.core.exceptions import ValidationError
from django.db import models
class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date
if self.status == 'draft' and self.pub_date is not done:
raise ValidationEroor('Draft entries may not have a publication date')
#Set the pub_date for published items if it hasn't been set already
if self.status == 'published' and self.pub_date is None:
self.pub_date = datetime.date.today()
모델의
*args, **kwargs
방법을 호출할 때 *args, **kwargs
방법을 자동으로 호출하지 않기 때문에views가 수동으로 호출해야 합니다.위의 예에서 save()
로 인한ValidationError 이상은 문자열을 통해 실례화되었기 때문에 특수한 오류 사전에 저장됩니다. 키는 NON 입니다.FIELD_ERRORS.이 키는 특정 필드 통과 오류 대신 모델 전체에 나타나는 오류에 사용됩니다.from django.core.exceptions import ValidationError, NON_FIELD_ERRORS
try:
article.full_clean()
except ValidationError as e:
non_field_errors = e.message_dict[NON_FIELD_ERRORS]
특정 필드에 이상을 일으키려면 사전의 키가 필드 이름인 ValidationError를 실례화할 수 있습니다.우리는 앞의 예를 업데이트하여
clean()
필드의 이상만 일으킬 수 있다.class Article(models.Model):
...
def clean(self):
# Don't allow draft entries to have a pub_date.
if self.status == 'draft' and self.pub_date is not None:
raise ValidationError({'pub_date': 'Draft entries may not have a publication date.'})
...
참조:https://djangobook.com/advanced-models/ http://python.usyiyi.cn/translate/django_182/ref/models/instances.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.