Django extra views
Published on septiembre 12th, 2015
"Django extra views" ens proporciona una manera fàcil, a través de les seves vistes "vitaminades", d'implementar els "formsets" per tal d'editar les relacions 1-n amb Django. Tambe tenir django-formset-js que ens "dinamitza" a través de Javascript la inserció i eliminació de tuples dels "formsets".
Per instal.lar les "django extra views" cal executar:
pip install django-extra-views
Per instal.lar django-formset-js cal executar:
pip install django-formset-js
i afegir l'aplicació al projecte:
INSTALLED\_APPS = (
...
'djangoformsetjs',
)
Detallant els passos, que serien:
Views:
-- encoding: utf-8 --
from crispy_forms.helper import FormHelper
from crispy_forms.layout import Layout
from crispy_forms.layout import Div
from django import forms
from extra_views import CreateWithInlinesView, UpdateWithInlinesView,
InlineFormSet
from backoffice.cars.models import AssuranceFeaturePrice,
EquipmentPrice, ChargePrice
from cms.cmscars.office.forms import AssuranceFeaturePriceForm,
EquipmentPriceForm, ChargePriceForm
views.py
class AssuranceFeaturePricesInline(InlineFormSet):
model = AssuranceFeaturePrice
form_class = AssuranceFeaturePriceForm
extra = 0
class EquipmentPricesInline(InlineFormSet):
model = EquipmentPrice
form_class = EquipmentPriceForm
extra = 0
class ChargePricesInline(InlineFormSet):
model = ChargePrice
form_class = ChargePriceForm
extra = 0
class OfficeCreateView(CreateWithInlinesView):
inlines = [AssuranceFeaturePricesInline, EquipmentPricesInline, ChargePricesInline]
class OfficeUpdateView(UpdateWithInlinesView):
inlines = [AssuranceFeaturePricesInline, EquipmentPricesInline, ChargePricesInline]
forms.py
[sourcecode language="python" wraplines="false" collapse="false"]
class AssuranceFeaturePriceForm(forms.ModelForm):
class Meta:
model = AssuranceFeaturePrice
fields = ('id', 'office', 'feature', 'price')
@property
def helper(self):
helper = FormHelper()
helper.label_class = 'col-xs-4'
helper.field_class = 'col-xs-6'
helper.form_tag = False
helper.layout = Layout(
'id', 'office', 'feature', 'price',
Div('DELETE', css_class='hidden')
)
return helper
class EquipmentPriceForm(forms.ModelForm):
class Meta:
model = EquipmentPrice
fields = ('id', 'office', 'equipment', 'price')
@property
def helper(self):
helper = FormHelper()
helper.label_class = 'col-xs-4'
helper.field_class = 'col-xs-6'
helper.form_tag = False
helper.layout = Layout(
'id', 'office', 'equipment', 'price',
Div('DELETE', css_class='hidden')
)
return helper
class ChargePriceForm(forms.ModelForm):
class Meta:
model = ChargePrice
fields = ('id', 'office', 'charge', 'price')
@property
def helper(self):
helper = FormHelper()
helper.label_class = 'col-xs-4'
helper.field_class = 'col-xs-6'
helper.form_tag = False
helper.layout = Layout(
'id', 'office', 'charge', 'price',
Div('DELETE', css_class='hidden')
)
return helper
[/sourcecode]
Template:
[sourcecode language="python" wraplines="false" collapse="false"]
############
# template #
############
{% block content2 %}
{{ form.media }}
<form id="form-office" method="post" action="{% if object %}{% url
update_url smydestination object.pk %}{% else %}{% url create_url
smydestination %}{% endif %}" class="form-horizontal">
{{ form.errors }}
{% crispy form %}
<!-- formsets -->
<div id="initial-precios" class="x_panel col-md-offset-2
col-md-7">
<div id="container-{{ formset.prefix }}">
<div class="x_title">
<h4>{% show_formset_name formset %}</h4>
</div>
<div class="formset well" data-formset-prefix="{{ formset.prefix }}">
<div class="errors">{{ formset.non_form_errors }}</div>
{{ formset.management_form }}
<div data-formset-body>
<div class="formset_item form-inline" data-formset-form>
{% crispy item %}
<button type="button" data-formset-delete-button class="btn
btn-danger pull-right"><i class="fa fa-trash"></i> {%
trans 'Borrar' %}</button>
</div>
{% endfor %}
</div>
<script type="form-template" data-formset-empty-form>
<div class="formset_item form-inline" data-formset-form>
{% crispy formset.empty_form %}
<button type="button" data-formset-delete-button class="btn
btn-danger pull-right"><i class="fa fa-trash"></i> {%
trans 'Borrar' %}</button>
</div>
{% endescapescript %}
</script>
<a class="btn btn-success" data-formset-add>
<i class="fa fa-plus-square-o"></i> {% trans 'Añadir
registro' %}
</a>
</div>
</div>
{% endfor %}
</div>
<!-- fin formsets -->
</form>
{% endblock content2 %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'js/jquery.formset.min.js' %}"></script>
<script type="text/javascript">
//<![CDATA[
$(function($) { $(".formset").formset({
animateForms: true, reorderMode: 'none', }); }); //\]\]>;
</script>;
{% endblock %}
A aquest exemple també es fa ús de Crispy Forms, per tal de millorar l'aparença dels formularis. Per instal.lar-ho:
pip install --upgrade django-crispy-forms
i afegir l'aplicació al projecte:
INSTALLED_APPS = (
...
'crispy_forms',
)
En aquest cas hi ha varis "formsets" relacionats amb el model principal. Per qüestió d'usabilitat s'ha implementat el formset dins un "Tab" del formulari principal. L'exemple exposat queda segons es mostra a l'imatge.
{.alignleft .size-large .wp-image-344 width="660" height="451"}
Per aprofondir en els paquets citats a l'exemple es recomana visitar els enllaços als mateixos.