El Django docs solo muestra ejemplos para anular save()
y delete()
. Sin embargo, me gustaría definir algún procesamiento adicional para mis modelos solo cuando se creen. Para cualquiera que esté familiarizado con Rails, sería el equivalente a crear un filtro :before_create
. es posible?Django - Anulando el método Model.create()?
Respuesta
Anulación de __init__()
provocaría que el código se ejecutara siempre que se instanciara la representación en python del objeto. No sé los rieles, pero un filtro :before_created
me parece que es un código que debe ejecutarse cuando el objeto se crea en la base de datos. Si desea ejecutar código cuando se crea un nuevo objeto en la base de datos, debe anular save()
, verificando si el objeto tiene un atributo pk
o no. El código sería algo como esto:
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)
Anulación __init__()
le permitirá ejecutar código cuando se crea una instancia del modelo. No olvides llamar al padre __init__()
.
Ah sí, esta fue la respuesta. No sé cómo pasé por alto esto. Gracias Ignacio. – ground5hark
un ejemplo de cómo crear una señal post_save (de 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)
aquí es una discusión seria sobre si lo mejor es utilizar señales o Reserva de encargo métodos http://www.martin-geber.com/thought/2007/10/29/django-signals-vs-custom-save-method/
En mi opinión, el uso de señales para esta tarea es más robusto, más fácil de leer pero más largo.
Esta es la forma preferida en lugar de jugar con objetos internos, sin embargo, si realiza modificaciones en el modelo en cuestión, y no solo crea otro en el ejemplo anterior, ** no olvide llamar a 'instance.save()' **. Entonces, en este caso, también hay una penalización de rendimiento ya que habrá una consulta INSERT y una UPDATE en la base de datos. –
Puede anular el método de creación con un administrador personalizado o agregar un método de clase en la clase de modelo. https://docs.djangoproject.com/en/1.11/ref/models/instances/#creating-objects
Para responder a la pregunta, literalmente, el método create
en el administrador de un modelo es una forma estándar de crear objetos nuevos en Django. Para anular, hacer algo como
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()
En este ejemplo, estoy anulando método método create
del gerente para hacer algún procesamiento adicional antes de que realmente se crea la instancia.
NOTA: código como
my_new_instance = MyModel.objects.create(my_field='my_field value')
va a ejecutar este método modificado create
, pero el código como
my_new_unsaved_instance = MyModel(my_field='my_field value')
no lo hará.
Esto es viejo, tiene una respuesta aceptada que funciona (Zach), y una más idiomática también (Michael Bylstra), pero como sigue siendo el primer resultado en Google la mayoría de la gente ve, Creo que necesitamos una mejor -practices estilo moderno-respuesta Django aquí:
El punto es el siguiente:
- señales de uso (leer más)
- utilizan un método para agradable n amespacing (si tiene sentido) ... y me marcó como
@classmethod
en lugar de@staticmethod
porque lo más probable que va a terminar necesidad de referirse miembros de la clase estática en el código
aún más limpio sería si núcleo de Django tener una señal real post_create
. (Imho si necesita pasar un argumento booleano para cambiar el comportamiento de un método, deberían ser 2 métodos).
- 1. administrador de django anulando método guardar en líneas?
- 2. Anulando un Método Java
- 3. método genérico Scala anulando
- 4. Spree anulando método de ayuda
- 5. Anulando "+ =" en Python? (Método __iadd __())
- 6. Anulando los métodos relacionados con Django
- 7. Fábricas/Accesorios contra simple Model.create (...)?
- 8. Anulando el método "igual": ¿cómo averiguar el tipo de parámetro?
- 9. Anulando un método variódico en objetivo-c
- 10. Práctica recomendada, anulando __construct() versus método init()
- 11. Anulando un método con un objeto
- 12. Anulando un método llamado por el constructor de una clase
- 13. Anulando un método de módulo de una gema en Rails
- 14. Java: Anulando un método abstracto en la subclase
- 15. Anulando un método de controlador con Sinatra y rspec
- 16. En Python, ¿cómo señalo que estoy anulando un método?
- 17. anulando upload_max_filesize
- 18. Constructor anulando
- 19. anulando Adapter.getView
- 20. Anulando Android ArrayAdapter
- 21. Django 1.4 - assertQuerysetEqual - cómo usar el método
- 22. Django cuándo usar el método de desmontaje
- 23. anulando el diseño after_sign_up_path_for not working
- 24. Anulando el operador 'to boolean' en python?
- 25. ¿Anulando el fondo del cuerpo con JQuery?
- 26. Anulando la función nativa?
- 27. C función ++ anulando
- 28. Anulando constantes en Java
- 29. Problema Anulando Bootstrap CSS
- 30. Anulando jQuery(). Load()
De hecho, he encontrado una solución usando señales: http://docs.djangoproject.com/en/dev/topics/signals/ (la señal pre_save, específicamente). Sin embargo, esta parece ser una solución mucho más pragmática. Gracias un montón. – ground5hark
buen truco. Todavía preferiría anular el método de crear porque me gustaría agregar una llamada a logging.info después de la creación de un nuevo objeto. Llamando antes y tienes la posibilidad de que falle la llamada al método principal ... – philgo20
Supongo que quieres pasar por alto el método de administrador 'create'? Esa es una solución interesante, pero no funcionaría en los casos en los que el objeto se crea usando 'Object (** kwargs) .save()' o cualquier otra variación sobre eso. – Zach