programing

Django-Model.create () 메서드 재정의?

nasanasas 2020. 11. 3. 08:07
반응형

Django-Model.create () 메서드 재정의?


장고 문서는 단지 오버라이드 (override)에 대한 예제 목록 save()delete(). 그러나 모델 이 생성 될 때만 모델에 대한 추가 처리를 정의하고 싶습니다 . Rails에 익숙한 사람이라면 :before_create필터 를 만드는 것과 같습니다 . 이것이 가능한가?


재정의 __init__()하면 객체의 파이썬 표현이 인스턴스화 될 때마다 코드가 실행됩니다. 레일을 모르지만 :before_created데이터베이스에서 개체가 생성 될 때 실행되는 코드처럼 필터가 들립니다. 데이터베이스에 새 객체가 생성 될 때 코드를 실행 save()하려면 객체에 pk속성 이 있는지 여부를 확인 하여을 재정의해야합니다 . 코드는 다음과 같습니다.

def save(self, *args, **kwargs):
    if not self.pk:
        # This code only happens if the objects is
        # not in the database yet. Otherwise it would
        # have pk
    super(MyModel, self).save(*args, **kwargs)

post_save 신호를 만드는 방법의 예 ( http://djangosnippets.org/snippets/500/ )

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save, sender=User)
def create_profile(sender, instance, created, **kwargs):
    """Create a matching profile whenever a user object is created."""
    if created: 
        profile, new = UserProfile.objects.get_or_create(user=instance)

다음은 신호 또는 사용자 지정 저장 방법을 사용하는 것이 가장 좋은지에 대한 신중한 토론입니다. https://web.archive.org/web/20120815022107/http://www.martin-geber.com/thought/2007/10/29/ django-signals-vs-custom-save-method /

제 생각에는이 작업에 신호를 사용하는 것이 더 강력하고 읽기 쉽지만 더 길다고 생각합니다.


이것은 오래되었고 작동하는 대답 (Zach 's)과 좀 더 관용적 인 대답 (Michael Bylstra 's)도 가지고 있지만 여전히 대부분의 사람들이 Google에서 보는 첫 번째 결과이기 때문에 더 많은 모범 사례 modern-django가 필요하다고 생각합니다. 여기 스타일 대답 :

from django.db.models.signals import post_save

class MyModel(models.Model):
    # ...
    @classmethod
    def post_create(cls, sender, instance, created, *args, **kwargs):
        if not created:
            return
        # ...what needs to happen on create

post_save.connect(MyModel.post_create, sender=MyModel)

요점은 다음과 같습니다.

  1. 신호 사용 ( 공식 문서에서 자세한 내용 참조 )
  2. 멋진 네임 스페이스를위한 메서드를 사용하십시오 (이치가 있다면) ... 그리고 코드에서 정적 클래스 멤버를 참조해야 할 가능성이 높기 때문에 @classmethod대신 다음과 같이 표시했습니다.@staticmethod

핵심 Django가 실제 post_create신호를 가지고 있다면 더 깨끗할 것 입니다. (메소드의 동작을 변경하기 위해 부울 인수를 전달해야하는 경우 Imho는 2 개의 메서드 여야합니다.)


문자 그대로 질문에 답하기 위해 create모델 관리자 메서드는 Django에서 새 개체를 만드는 표준 방법입니다. 재정의하려면 다음과 같이하십시오.

from django.db import models

class MyModelManager(models.Manager):
    def create(self, **obj_data):
        # Do some extra stuff here on the submitted data before saving...
        # For example...
        obj_data['my_field'] = my_computed_value(obj_data['my_other_field'])

        # Now call the super method which does the actual creation
        return super().create(**obj_data) # Python 3 syntax!!

class MyModel(models.model):
    # An example model
    my_field = models.CharField(max_length=250)
    my_other_field = models.CharField(max_length=250)

    objects = MyModelManager()

이 예에서는 create인스턴스가 실제로 생성되기 전에 몇 가지 추가 처리를 수행하기 위해 Manager의 메서드 메서드를 재정의합니다 .

참고 : 다음 과 같은 코드

my_new_instance = MyModel.objects.create(my_field='my_field value')

이 수정 된 create메서드 를 실행 하지만 다음과 같은 코드

my_new_unsaved_instance = MyModel(my_field='my_field value')

하지 않을 것이다.


Overriding __init__() will allow you to execute code when the model is instantiated. Don't forget to call the parent's __init__().


You can override the create method with a custom manager or add a classmethod on the model class. https://docs.djangoproject.com/en/1.11/ref/models/instances/#creating-objects


The preferred answer is correct but the test to tell whether the object is being created doesn't work if your model derives from UUIDModel. The pk field will already have a value.

In this case, you can do this:

already_created = MyModel.objects.filter(pk=self.pk).exists()

참고URL : https://stackoverflow.com/questions/2307943/django-overriding-the-model-create-method

반응형