//barrabarra

JAVIER ROMERO
Programación web y escritorio
 

Our blog, keeping you up-to-date on our latest news.

 

Django: Comprobar en un método clean si se actualiza o se añade un objeto

noviembre 19, 2010 at 2:19 pm | Blog, Programación | No comment

 

Esto me ha costado meses descubrirlo.

Desde los primeros días que empecé a programar en Django me encontré con que no tenía un modo simple de comprobar que sólo existiese un objeto, podía comprobar que el count de un queryset fuera < 1, pero cuando iba a actualizarlo plaf, no podía porque efectivamente ya existía un objeto.

La solución está en usar la propiedad initial, que nos devuelve un diccionario con el contenido anterior si es que se va a actualizar el objeto, o un diccionario vacío en caso contrario, con lo que ya se puede diferenciar una situación de la otra.


class CategoryAdminForm(forms.ModelForm):



"""

Formulario para comprobar que no se intentan guardar dos categorías en el mismo nivel/con mismo padre

"""



def clean_slug(self):

    if not self.initial:

        raise forms.ValidationError(_(u'Ya existe uno'))

        return data

 

Django: acceder al value de los campos de un formulario

marzo 27, 2010 at 8:47 pm | Blog, Programación | No comment

 

Recientemente he tenido que preparar una plantilla en django que mostrara una serie de imágenes del usuario y un formulario adyacente en el que podían sustituir esta, así que me encontraba con el problema de mostrar al usuario sus fotos actuales, si es que tenían.

Para ello se crea un formulario heredando del modelo:


forms.py:
class PhotosForm(forms.ModelForm):
   photo = forms.ImageField(label=_(u'Fotografía'), required=False)
   current = forms.CharField(label='', widget=forms.HiddenInput(), required=False)

   class Meta:
      model = ProfilePhotos
      exclude = ('profile','accepted',)

Luego, en la vista, puedes consultar el perfil del usuario en cuestión y ver si tiene fotografías:


views.py
@login_required
def edit_photos(request, template_name='members/photos.html'):
   page_title = _(u'Editar fotografías')
   PhotosFormSet = formset_factory(PhotosForm, extra=5, max_num=5)
   profile = request.user.profiles_set.filter(accepted=True).latest('date')

   if request.method == 'POST':
       ...
   else:
      profile_photos = profile.profilephotos_set.filter(accepted=True)
      if profile_photos:
         data = []
         for photo in profile_photos:
            data.append({'current': photo.photo.name})
         formset = PhotosFormSet(initial = data)
      else:
         formset = PhotosFormSet()

Y finalmente, en la plantilla se puede acceder a los valores de los campos mediante


photos.html:
   {{ formset.management_form }}
   {% for photos_form in formset.forms %}
   

   {% if photos_form.initial.current %}
      [img src="{{photos_form.initial.current }}" alt="" /]
   {% else %}
      [img src="default.jpg" alt="" /]
   {% endif %}
   

   ...

Y del mismo modo, se puede acceder mediante form.initial.nombre_clave a cualquier otro dato inicial.

Si en lugar de proporcionar datos iniciales lo que hacemos es asociar el formulario a una instancia ( form.is_bound == True ) entonces podremos acceder a los datos mediante form.data.nombre_clave

Bah, como salta a la vista, el formateo de código de WordPress no es muy bueno…

 

Categorias:

Archivo: