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