Como utilizar os inlines no front para os ModelForms (function based view). Faremos algo bem similar com alguns detalhes a mais.
Objetivo é fornecer um formulário de cadastro e este pode fazer uploads de fotos. Quando o email já existir no banco de dados, faremos que as fotos do segundo envio seja direcionadas para o primeiro cadastro, do contrário, uma nova instancia para todos os objetos envolvidos.
models.py
from django.db import models # Create your models here. class Cadastro(models.Model): """(Cadastro description)""" nome = models.CharField(max_length=255) email = models.EmailField(verbose_name='E-mail') telefone = models.CharField(max_length=20) aceite = models.BooleanField(default=True) data = models.DateField(auto_now_add=True) hora = models.TimeField(auto_now_add=True) class Meta: verbose_name, verbose_name_plural = u"Cadastro" , u"Cadastros" ordering = ('-data',) def __unicode__(self): return "%s" % self.nome class Foto(models.Model): """(Foto description)""" cadastro = models.ForeignKey(Cadastro) foto = models.ImageField(upload_to="uploads/fotos/foto/%Y") data = models.DateField(auto_now_add=True) hora = models.TimeField(auto_now_add=True) aprovado = models.BooleanField(default=False) class Meta: verbose_name, verbose_name_plural = u"Foto" , u"Fotos" ordering = ('-data',) def __unicode__(self): return "%s" % self.id def thumb_admin(self): from sorl.thumbnail import get_thumbnail im = get_thumbnail(self.foto, '120x120', crop='center', quality=99) if im: return '<a href="http://www.blogger.com/media/%s" onclick="window.open(this.href);return false;"><img alt="Imagem" src="%s" /></a>' % (self.foto, str(im.url)) return 'Sem foto' thumb_admin.is_safe = True thumb_admin.allow_tags = True thumb_admin.short_description = 'Thumb'
admin.py
from django import forms from django.contrib import admin from .models import * class FotoInline(admin.TabularInline): model = Foto readonly_fields = ['foto',] extra = 5 class CadastroAdmin(admin.ModelAdmin): inlines = [ FotoInline, ] search_fields = ('nome', 'email',) list_display = ('nome', 'email','telefone','data', 'hora',) list_filter = ['data',] date_hierarchy = 'data' readonly_fields = ['nome', 'email','telefone','aceite'] save_on_top = True admin.site.register(Cadastro, CadastroAdmin) class FotoAdmin(admin.ModelAdmin): list_display = ('cadastro', 'data', 'hora','thumb_admin','aprovado') list_filter = ['data','aprovado'] date_hierarchy = 'data' list_editable = ['aprovado'] readonly_fields = ['cadastro','foto',] save_on_top = True admin.site.register(Foto, FotoAdmin)
forms.py
# coding: utf-8 from django import forms from django.utils.translation import ugettext_lazy as _ from .models import * from util import util as U from django.forms.models import inlineformset_factory class CadastroForm(forms.ModelForm): class Meta: model = Cadastro class FotoForm(forms.ModelForm): aprovado = forms.BooleanField(initial=False, required=False) aceite = forms.BooleanField(initial=True) class Meta: model = Foto def dados(self): return {'form':self.cleaned_data, 'data':datetime.now()} def clean(self): cleaned_data = super(FotoForm, self).clean() #if cleaned_data.get("senha") != cleaned_data.get("confirme"): # self._errors["confirme"] = self.error_class(['Senha nao confere']) return self.cleaned_data FotoFormSet = inlineformset_factory(Cadastro, Foto, extra=5)
urls.py
# coding: utf-8 from django.conf.urls.defaults import patterns, include, url from . import views urlpatterns = patterns('fotos.views', url(r'^$', views.CadastroView.as_view(), name='cadastro_form'), )
form.html
<html> <head> <meta charset="utf-8"> <title></title> </head> <body> <form action="" method="post" enctype="multipart/form-data"> {% csrf_token %} {{ form.errors }} <p>Nome:{{ form.nome }}</p> <p>Telefone: {{ form.telefone }}</p> <p>E-mail: {{ form.email }}</p> <p>Foto: {{ form.foto }}</p> <p>Aceite: {{ form.aceite }}</p> {{ foto_formset.management_form }} {% for form in foto_formset %} {{ form.id }} <div class="form-row inline {{ foto_formset.prefix }}"> {{ form.foto.label_tag }} {{ form.foto }} {{ form.foto.errors }} </div> {% endfor %} <input type="submit" name="" value="Enviar"> </form> </body> </html>
views.py
class CadastroView(CreateView): #template_name = 'form.html' template_name = 'index.html' model = Cadastro form_class = CadastroForm success_url = '/envie/?sucesso=1#sucesso' def form_valid(self, form): context = self.get_context_data() foto_form = context['foto_formset'] email = form.cleaned_data['email'] if foto_form.is_valid(): print "erros: %s" % foto_form.errors if Cadastro.objects.filter(email=email): foto_form.instance = Cadastro.objects.get(email=email) else: self.object = form.save() foto_form.instance = self.object foto_form.save() return HttpResponseRedirect('/envie/?sucesso=1#sucesso') else: addDebug("erros: %s" % foto_form.errors) return self.render_to_response(self.get_context_data(form=form)) def form_invalid(self, form): return self.render_to_response(self.get_context_data(form=form)) def get_context_data(self, **kwargs): context = super(CadastroView, self).get_context_data(**kwargs) r = self.request.POST f = self.request.FILES if r and f: context['foto_formset'] = FotoFormSet(self.request.POST,f) else: context['foto_formset'] = FotoFormSet() return context
cadastro.js
jQuery(document).ready(function($) { $('.bt-mais').click(function(event) { if($('.enviar-foto-fake').length < 5){ $('.enviar-foto-fake').last().clone().insertAfter($('.enviar-foto-fake').last()); $('.enviar-foto-fake').last().find('div p.nome-foto').text('Você pode enviar até cinco fotos'); $('.enviar-foto-fake').last().find('input').attr({ id: 'id_foto_set-'+($('.enviar-foto-fake').length-1)+'-foto', name: 'foto_set-'+($('.enviar-foto-fake').length-1)+'-foto' }); $('#id_foto_set-TOTAL_FORMS').val($('.enviar-foto-fake').length); } if ($('.enviar-foto-fake').length == 5) { $(this).hide(); }; }) });
hasta!
Nenhum comentário:
Postar um comentário