Django-переопределение модели.метод create ()?



The Django docs только список примеров для того, чтобы переопределить save() и delete(). Тем не менее, я хотел бы определить некоторые дополнительные обработки для моих моделей только когда они созданы. Для тех, кто знаком с Rails, это было бы эквивалентно созданию :before_create фильтр. Это возможно?

1087   6  

6 ответов:

переопределение __init__() вызовет выполнение кода всякий раз, когда создается экземпляр представления объекта python. Я не знаю рельсов, но a :before_created фильтр звучит для меня, как это код, который будет выполняться, когда объект создается в базе данных. Если вы хотите выполнить код при создании нового объекта в базе данных, вы должны переопределить save(), проверка наличия объекта или нет. Код будет выглядеть примерно так:

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)

вот вдумчивое обсуждение того, лучше ли использовать сигналы или пользовательские методы сохраненияhttp://www.martin-geber.com/thought/2007/10/29/django-signals-vs-custom-save-method/

на мой взгляд, использование сигналов для этой задачи более надежно, легче читать, но длиннее.

Это старый, имеет принятый ответ, который работает (Зак), и более идиоматический тоже (Майкл Былстра), но поскольку это все еще первый результат в Google, большинство людей видят,Я думаю, что нам нужен более передовой опыт modern-django style ответ здесь:

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 если вам нужно передать логический arg, чтобы изменить поведение метода, это должно быть 2 метода.)

переопределение __init__() позволит вам выполнить код при создании экземпляра модели. Не забудьте позвонить родителям __init__().

вы можете переопределить метод create с помощью пользовательского менеджера или добавить classmethod в класс модели. https://docs.djangoproject.com/en/1.11/ref/models/instances/#creating-objects

ответить на вопрос буквально, то 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 метод для выполнения дополнительной обработки перед фактическим созданием экземпляра.

Примечание: код

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

выполнит это изменение create метод, но код вроде

my_new_unsaved_instance = MyModel(my_field='my_field value')

не будет.

Comments

    Ничего не найдено.