2010-11-03 19 views
5

Necesito establecer el valor del campo, que no se pasa al constructor de Formulario Django.Establezca el valor del campo en el método Django Form clean(), si este campo no se pasa en el constructor

que tienen el modelo y la forma como esta:

class Message(models.Model): 
    created  = models.DateTimeField() 
    text  = models.CharField(max_length=200, blank=True, null=True) 
    active  = models.BooleanField(default=False) 

class MessageForm(forms.ModelForm): 
    class Meta: 
     model = Message 
     exclude = ('created', 'active') 

    def clean(self): 
     # check if user is blocked 
     if user.is_admin(): 
      self.cleaned_data['active'] = True 
     return self.cleaned_data 

preverse: si el usuario actual es admin - Necesito ajusta automáticamente mensaje como activo. El usuario no debe pasar este parámetro por formulario.

real: veo que mensaje guardado siempre tienen la bandera "falso" (puedo eliminar condiciones y en este caso también veo que el mensaje no está activo).

Por favor, ayúdame a entender, ¿cómo puedo yo establecer este "activa" bandera en limpia método().

+1

¿Cómo y de dónde viene el "usuario" variable de conseguir el sistema? –

+0

Yo blanco esto por ejemplo. Puede eliminar esta condición o reemplazar en algo más. He establecido self.cleaned_data ['active'] = True pero también necesito decirle a Django Form que este campo se usa y necesito establecer este valor en el objeto antes de guardarlo. Puedo hacer esto con el parámetro "inicial" para el objeto Formulario, pero no puedo hacerlo en mi caso. Necesito decirle a Django Form que he usado el campo "activo", pero no sé cómo hacerlo en un método de método clean(). –

Respuesta

4

la respuesta anterior funcionaría, pero me gusta que encapsula las operaciones internas de toda la forma como qué mostrar y qué no, dentro de la forma. Sé que usted mencionó que no quiere enviar un valor de campo al constructor, pero si no le importa enviar al usuario, su solución funcionaría. es decir, su constructor:

def __init__(self, user): 
    self.user = user 
    super(BaseForm, self).__init__() 

continuación, en su limpia, que acaba de cambiar el user-self.user. Hay otro beneficio adicional a esto. Digamos que mañana quiere asignar más campos según su usuario, no necesita agregar nada a las vistas, simplemente puede agregarlo al formulario.

EDIT: Cuando agrega un campo para excluir, no está disponible en los datos limpios. En cambio, configure su widget como oculto.

active = forms.BooleanField(widget=forms.HiddenInput) 

EDIT 2: Si realmente no quiere que el campo en el formulario En este caso, en lugar de anular la limpieza, ¿por qué no se reemplaza el salve?

def save (self): 
    super(BaseForm, self).save() 
    if user.is_admin(): 
     self.instance.active=True 
    super(BaseForm, self).save() 
+0

Objeto de usuario: esto no es un problema. El problema no está en clean_data del objeto guardado. Si configuro self.cleaned_data ['active'] = True en result este campo no se ve afectado. Necesito decirle a Formulario que he usado el campo "activo" en este procesamiento de formularios, como los datos iniciales que se pasan en el constructor de formularios. –

+0

Simplemente vuelva a verificar su formulario. El problema es que cuando excluye un campo de un formulario, no está disponible en los datos limpios. En cambio, incluya el atributo y establezca su widget en oculto. mira mi edición – zsquare

+0

He establecido datos en self.cleaned_data - esto está bien. Pero necesito decirle a Django Form que use este campo. ¿Como hacer esto? –

3

No haga esto en el método clean() de formulario, haga esto en la vista.

def your_view(request): 
    if request.method == 'POST': 
     form = MessageForm(data=request.POST) 
     if form.is_valid(): 
      new_message = form.save(commit=False) 
      if user.is_admin(): 
       new_message.active = True 

Sin embargo, si también quiere manejar el caso en que el usuario es no administrador usando la misma forma, se puede ver en la incorporación de una lógica similar en init del formulario() en lugar de la vista, probablemente por pasar información sobre el usuario desde el punto de vista de inicialización del formulario()

+0

Describo a continuación que necesito hacer esto en la lógica del modelo o en la lógica de formularios. En la vista, esta manera fácil no es para mi tarea. Si el usuario trabaja en la sección de administración, necesito activar mi lógica personalizada. Si hago esta lógica a la vista, esto no funciona en todos los demás lugares, ¡y esto no es bueno! –

0

Utilice esta:

def message_form_factory(user): 
    class MessageForm(forms.ModelForm): 
     def clean(self): 
      # check if user is blocked 
      if user.is_admin(): 
       self.cleaned_data['active'] = True 
      return self.cleaned_data 
    return MessageForm 

Y en su opinión utilización:

form = message_form_factory(request.user)() 
form = message_form_factory(request.user)(request.POST) 
+0

En Django admin necesito usar funcional con lógica personalizada. Su solución se puede usar en administración con formulario personalizado, pero este código adicional alrededor del proyecto. Creo que esta no es una buena solución en mi caso. ¡Gracias! –

+0

Por lo que puedo leer, no mencionaste nada sobre el administrador de Django en tu pregunta ... –

Cuestiones relacionadas