Django-переопределение модели.метод create ()?
The Django docs только список примеров для того, чтобы переопределить save() и delete(). Тем не менее, я хотел бы определить некоторые дополнительные обработки для моих моделей только когда они созданы. Для тех, кто знаком с Rails, это было бы эквивалентно созданию :before_create фильтр. Это возможно?
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)дело вот в чем:
- использовать сигналы (подробнее здесь в официальных документах)
- используйте метод для хорошего пространства имен (если это имеет смысл)...и я отметил это как
@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