urls tutorial superusuario personalizar createsuperuser crear commands django django-admin

tutorial - python django documentation



Mostrar excepciones de validaciĆ³n de modelo personalizadas en el sitio de administraciĆ³n de Django (4)

Tengo un modelo de reserva que necesita verificar si el artículo que se está reservando está disponible. Me gustaría tener la lógica detrás de averiguar si el elemento está disponible centralizado para que no importa dónde guarde la instancia, este código valida que se puede guardar.

En este momento tengo este código en una función de guardado personalizada de mi clase de modelo:

def save(self): if self.is_available(): # my custom check availability function super(MyObj, self).save() else: # this is the bit I''m stuck with.. raise forms.ValidationError(''Item already booked for those dates'')

Esto funciona bien: el error se genera si el elemento no está disponible y mi elemento no se guarda. Puedo capturar la excepción de mi código de formulario de front-end, pero ¿qué pasa con el sitio de administración de Django? ¿Cómo puedo hacer que se muestre mi excepción como cualquier otro error de validación en el sitio de administración?



Bastante viejo post, pero creo que "usar limpieza personalizada" sigue siendo la respuesta aceptada. Pero no es satisfactorio. Puede realizar la comprobación previa que desee, pero aún así puede obtener una excepción en Model.save() , y es posible que desee mostrar un mensaje al usuario de una manera consistente con un error de validación de formulario.

La solución que encontré fue anular ModelAdmin.changeform_view() . En este caso, estoy detectando un error de integridad generado en algún lugar del controlador SQL:

from django.contrib import messages from django.http import HttpResponseRedirect def changeform_view(self, request, object_id=None, form_url='''', extra_context=None): try: return super(MyModelAdmin, self).changeform_view(request, object_id, form_url, extra_context) except IntegrityError as e: self.message_user(request, e, level=messages.ERROR) return HttpResponseRedirect(form_url)


En django 1.2, se ha agregado la validación del modelo.

Ahora puede agregar un método "limpio" a sus modelos que generan excepciones de ValidationError, y se llamará automáticamente cuando use el administrador de django.

(No queda muy claro en la documentación que el administrador llame al método de limpieza, pero lo he verificado aquí)

http://docs.djangoproject.com/en/dev/ref/models/instances/?from=olddocs#validating-objects

Entonces tu método limpio podría ser algo como esto:

from django.core.exceptions import ValidationError class MyModel(models.Model): def is_available(self): #do check here return result def clean(self): if not self.is_available(): raise ValidationError(''Item already booked for those dates'')

No lo he usado extensivamente, pero parece mucho menos código que tener que crear un ModelForm, y luego vincular ese formulario en el archivo admin.py para usarlo en django admin.


También he intentado resolver esto y está mi solución, en mi caso, necesitaba rechazar cualquier cambio en los objetos relacionados si el objeto principal está bloqueado para editar.

1) Excepción personalizada

class Error(Exception): """Base class for errors in this module.""" pass class EditNotAllowedError(Error): def __init__(self, msg): Exception.__init__(self, msg)

2) metaclase con método de guardado personalizado, todos mis modelos de datos relacionados se basarán en esto:

class RelatedModel(models.Model): main_object = models.ForeignKey("Main") class Meta: abstract = True def save(self, *args, **kwargs): if self.main_object.is_editable(): super(RelatedModel, self).save(*args, **kwargs) else: raise EditNotAllowedError, "Closed for editing"

3) metaforma: todos mis formularios de administración de datos relacionados se basarán en esto (asegurará que la interfaz de administración informará al usuario sin error de interfaz de administración):

from django.forms import ModelForm, ValidationError ... class RelatedModelForm(ModelForm): def clean(self): cleaned_data = self.cleaned_data if not cleaned_data.get("main_object") raise ValidationError("Closed for editing") super(RelatedModelForm, self).clean() # important- let admin do its work on data! return cleaned_data

En mi opinión, no es tanto una sobrecarga y sigue siendo bastante sencillo y fácil de mantener.