Django docs только список примеров для переопределения save()
и delete()
. Тем не менее, я бы хотел определить некоторую дополнительную обработку для своих моделей только тогда, когда они созданы. Для тех, кто знаком с Rails, это будет эквивалентно созданию фильтра :before_create
. Это возможно?Django - переопределение метода Model.create()?
ответ
Переопределение __init__()
приведет к тому, что код будет выполняться всякий раз, когда создается представление объекта python. Я не знаю рельсы, но фильтр :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)
Переопределение __init__()
позволит вам выполнить код при создании экземпляра модели. Не забудьте вызвать родителя __init__()
.
А да, это был ответ. Не знаю, как я это забыл. Спасибо Игнасио. – ground5hark
пример того, как создать сигнал 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/
По-моему, использование сигналов для этой задачи более надежное, более легкое для чтения, но более длительное.
Это предпочтительный способ вместо возиться с внутренними объектами, однако, если вы вносите изменения в рассматриваемую модель, а не просто создаете другую в приведенном выше примере, ** не забудьте вызвать 'instance.save()' **. Таким образом, в этом случае также наблюдается снижение производительности, поскольку в базу данных будет один запрос INSERT и один UPDATE. –
Вы можете переопределить метод create с помощью настраиваемого менеджера или добавить класс класса в класс модели. 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')
не будет.
Это старый, имеет принятый ответ, который работает (Zach's), и более идиоматический (Michael Bylstra's), но поскольку он по-прежнему является первым результатом в Google, который большинство людей видит, Я думаю, нам нужно больше -practices современного стиль Джанго здесь ответ:
Дело заключается в следующем:
- использовать сигналы (далее)
- использовать метод для хорошего п amespacing (если это имеет смысл) ... и Я пометил его как
@classmethod
вместо@staticmethod
, потому что, скорее всего, вы будете в конечном итоге нужно ссылаться членов статических классов в коде
Даже очиститель будет, если ядро Django будет имеют фактический сигнал post_create
. (Имхо, если вам нужно передать логический аргумент, чтобы изменить поведение метода, это должно быть 2 метода.)
- 1. Переопределение метода аутентификации - admin Django
- 2. Django: переопределение метода save() в модели
- 3. Переопределение метода get_form_class() Django throws string error
- 4. Переопределение метода обновления набора запросов Django
- 5. Переопределение метода save() модели, использующей django-mptt
- 6. Переопределение метода
- 7. Переопределение метода
- 8. Переопределение метода сохранения против метода модели?
- 9. Переопределение метода отправки PHPMailer
- 10. Переопределение виртуального метода
- 11. Переопределение метода реактивного компонента
- 12. Переопределение абстрактного метода TimerTask.Run()
- 13. Переопределение метода в Javascript
- 14. Переопределение или перехват метода
- 15. Переопределение метода прогона
- 16. Переопределение метода Java
- 17. Переопределение метода jQuery Dialog
- 18. Переопределение метода перегрузки оператора
- 19. Переопределение метода дженериков ошибок
- 20. Переопределение метода отправки XMLHttpRequest
- 21. Переопределение синхронизированного метода
- 22. C# Переопределение метода GetHashCode
- 23. Переопределение метода в Groovy
- 24. Переопределение метода paint()
- 25. Переопределение метода класса ActiveRecord
- 26. Переопределение метода, который дает
- 27. Java Generics - переопределение метода
- 28. Переопределение метода() в SwingWorker
- 29. Java: переопределение интерфейса метода
- 30. Переопределение метода DataGridViewTextBoxCell Paint
Я действительно нашел решение, используя сигналы: http://docs.djangoproject.com/en/dev/topics/signals/ (сигнал pre_save, в частности). Однако это представляется гораздо более прагматичным решением. Огромное спасибо. – ground5hark
красивый взлом. Я бы предпочел переопределить метод create, так как я хотел бы добавить вызов logging.info после создания нового объекта. Вызвав его раньше, и у вас есть вероятность того, что вызов родительского метода завершится неудачно ... – philgo20
Предполагаю, вы имеете в виду переопределение метода-менеджера 'create'? Это интересное решение, но оно не будет работать в случаях, когда объект создается с помощью 'Object (** kwargs) .save()' или любой другой вариант. – Zach