Use a formset in submit layer form to handle maintainers

Formsets allow us to have separate fields for name/email for each
maintainer, as well as being able to collect the responsibility field
value. Also split the form to be output field-by-field to allow styling.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2013-02-25 10:47:37 +00:00
parent d8c6824f30
commit 3964071e9d
3 changed files with 66 additions and 30 deletions

View File

@ -4,14 +4,42 @@
#
# Licensed under the MIT license, see COPYING.MIT for details
from layerindex.models import LayerItem
from layerindex.models import LayerItem, LayerMaintainer
from django import forms
from django.core.validators import URLValidator, RegexValidator, email_re
from django.forms.models import inlineformset_factory
import re
class LayerMaintainerForm(forms.ModelForm):
class Meta:
model = LayerMaintainer
fields = ('name', 'email', 'responsibility')
def clean_email(self):
email = self.cleaned_data['email'].strip()
if email:
if len(email) < 7:
raise forms.ValidationError('%s is not a valid email address' % email)
reg = re.compile(email_re)
if not reg.match(email):
raise forms.ValidationError('%s is not a valid email address' % email)
return email
class BaseLayerMaintainerFormSet(forms.models.BaseInlineFormSet):
def _construct_form(self, i, **kwargs):
f = super(BaseLayerMaintainerFormSet, self)._construct_form(i, **kwargs)
# Ensure the first form in the formset gets filled in
if i == 0:
f.empty_permitted = False
f.required = True
return f
LayerMaintainerFormSet = inlineformset_factory(LayerItem, LayerMaintainer, form=LayerMaintainerForm, formset=BaseLayerMaintainerFormSet, can_delete=False)
class SubmitLayerForm(forms.ModelForm):
# Additional form fields
maintainers = forms.CharField(max_length=200)
deps = forms.ModelMultipleChoiceField(label='Other layers this layer depends upon', queryset=LayerItem.objects.all(), required=False)
class Meta:
@ -55,21 +83,3 @@ class SubmitLayerForm(forms.ModelForm):
val = URLValidator(verify_exists=False)
val(url)
return url
def clean_maintainers(self):
maintainers = self.cleaned_data['maintainers'].strip()
addrs = re.split(r'"?([^"@$<>]+)"? *<([^<> ]+)>,? *', maintainers)
addrs = [addr.strip() for addr in addrs if addr]
if addrs and len(addrs) % 2 == 0:
addrdict = {}
reg = re.compile(email_re)
for i in range(0, len(addrs)-1,2):
email = addrs[i+1]
if not reg.match(email):
raise forms.ValidationError('%s is not a valid email address' % email)
addrdict[addrs[i]] = email
maintainers = addrdict
else:
raise forms.ValidationError('Please enter one or more maintainers in email address format (i.e. "Full Name <emailaddress@example.com> separated by commas")')
return maintainers

View File

@ -20,7 +20,36 @@
<form action="{% url submit_layer %}" method="post">
{% csrf_token %}
{{ form.as_p }}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{{ field.help_text }}
</div>
{% endfor %}
<h3>Maintainers</h3>
{{ maintainerformset.non_form_errors }}
{{ maintainerformset.management_form }}
{% for maintainerform in maintainerformset %}
<h4>Maintainer {{forloop.counter}}</h4>
{% for hidden in maintainerform.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in maintainerform.visible_fields %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{{ field.help_text }}
</div>
{% endfor %}
{% endfor %}
<input type="submit" value="Submit" class='btn' />
</form>

View File

@ -12,7 +12,7 @@ from django.template import RequestContext
from layerindex.models import LayerItem, LayerMaintainer, LayerDependency, Recipe
from datetime import datetime
from django.views.generic import DetailView, ListView
from layerindex.forms import SubmitLayerForm
from layerindex.forms import SubmitLayerForm, LayerMaintainerFormSet
from django.db import transaction
from django.contrib.auth.models import User, Permission
from django.db.models import Q
@ -27,17 +27,12 @@ def submit_layer(request):
if request.method == 'POST':
layeritem = LayerItem()
form = SubmitLayerForm(request.POST, instance=layeritem)
if form.is_valid():
maintainerformset = LayerMaintainerFormSet(request.POST, instance=layeritem)
if form.is_valid() and maintainerformset.is_valid():
with transaction.commit_on_success():
layeritem.created_date = datetime.now()
form.save()
# Save maintainers
for name, email in form.cleaned_data['maintainers'].items():
maint = LayerMaintainer()
maint.layer = layeritem
maint.name = name
maint.email = email
maint.save()
maintainerformset.save()
# Save dependencies
for dep in form.cleaned_data['deps']:
deprec = LayerDependency()
@ -63,9 +58,11 @@ def submit_layer(request):
return HttpResponseRedirect(reverse('submit_layer_thanks'))
else:
form = SubmitLayerForm()
maintainerformset = LayerMaintainerFormSet()
return render(request, 'layerindex/submitlayer.html', {
'form': form,
'maintainerformset': maintainerformset,
})
def submit_layer_thanks(request):