Django에서 모델 관리자 사용자화 및 방법

15681 단어
1. 관리자 사용자화
문에서 Book.objects.all()에서 objects는 특수한 속성으로 데이터베이스를 조회하는데 그것이 바로 모델의 관리자이다.모든 Django 모델에는 최소한 하나의 관리자가 있습니다. 사용자 정의 관리자를 만들어서 데이터베이스에 접근할 수 있습니다.사용자 정의 관리자를 만드는 두 가지 방법이 있습니다: 추가 관리자를 추가합니다.관리자가 반환하는 초기 Queryset을 수정합니다.
추가 관리자 추가
추가 관리자를 추가하는 것은 모듈에 표급 기능을 추가하는 최선의 방법이다.(행급 기능, 즉 모델 실례 대상에만 작용하는 함수는 사용자 정의 모델 방법을 통해 실현된다).예를 들어 Book 모형에 title_count()의 manger 방법을 추가하면 keyword를 수신하고 제목에 포함된 책의 수량을 되돌려줍니다.
models.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는 관리자 자체를 가리킨다.모델의 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.'})
        ...

좋은 웹페이지 즐겨찾기