Django 모델의 사용자 정의 요약

7312 단어
1. 관리자 사용자화
문에서 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

좋은 웹페이지 즐겨찾기