Ver Mensaje Individual
  #1 (permalink)  
Antiguo 24/12/2014, 09:21
Avatar de kojicomics
kojicomics
 
Fecha de Ingreso: junio-2013
Mensajes: 49
Antigüedad: 11 años, 5 meses
Puntos: 1
Campos opcionales con UserChangeForm

Hola a todos

Tengo un modelo de usuarios extendido mediante 'AbstractUser':

models.py
Código Python:
Ver original
  1. from django.db import models
  2. from django.contrib.auth.models import AbstractUser
  3.  
  4.  
  5. class Profiles(AbstractUser):
  6.     url = models.URLField()
  7.     avatar = models.ImageField(upload_to='profile_avatar')

Tengo también un formulario para modificar los usuarios basado en 'UserChangeForm':

forms.py
Código Python:
Ver original
  1. from django import forms
  2. from django.contrib.auth.forms import UserChangeForm
  3. from django.utils.translation import ugettext as _
  4. from .models import Profiles
  5.  
  6.  
  7. class UserEditForm(UserChangeForm):
  8.  
  9.     class Meta:
  10.         model = Profiles
  11.         fields = ('username', 'first_name', 'last_name', 'email', 'url',
  12.                   'avatar',)
  13.         exclude = ('password',)
  14.  
  15.     def clean_username(self):
  16.         username = self.cleaned_data['username']
  17.         try:
  18.             Profiles.objects.get(username=username)
  19.         except Profiles.DoesNotExist:
  20.             return username
  21.         raise forms.ValidationError(_('Duplicate username'))
  22.  
  23.     def clean_avatar(self):
  24.         avatar = self.cleaned_data['avatar']
  25.         if avatar:
  26.             if avatar._size > 1024 * 1024:
  27.                 raise forms.ValidationError(_('Image file too large ( > 1mb )'))
  28.             return avatar
  29.         else:
  30.             raise forms.ValidationError(_("Couldn't read uploaded image"))
  31.  
  32.     def clean_password(self):
  33.         return ""

El formulario lo ejecuto mediante esta vista:

views.py
Código Python:
Ver original
  1. from django.views.generic import UpdateView
  2. from .models import Profiles
  3. from .forms import UserEditForm
  4.  
  5.  
  6. class UserEdit(UpdateView):
  7.     model = Profiles
  8.     form_class = UserEditForm
  9.     success_url = reverse_lazy('profile')
  10.     template_name = 'profile/edit.html'
  11.  
  12.     def get_object(self, queryset=None):
  13.         return self.request.user

El formulario de modificación funciona correctamente en la aplicación, pero tengo dos problemas:

El primero es que el formulario requiere que el usuario inserte obligatoriamente los campos adicionales (los de mi modelo extendido) para poder enviar el formulario.

Lo he solucionado redefiniendo los campos dentro del formulario junto con el atributo "required=False" pero me gustaría saber si hay algún método de aplicar ésto a todos los campos sin tener que modificarlos uno a uno.

El segundo problema, y el más importante, es que los campos que el usuario no rellene en el formulario, en vez de ignorarlos, elimina su valor anterior.

Una posible solución es generar el valor de las etiquetas dinámicamente mediante:
Código:
value={{user.fieldname}}
Pero en caso de eliminar el valor de un campo volveríamos al mismo problema.

Un saludo, Gracias