diff options
Diffstat (limited to 'ishtar_common/forms_common.py')
-rw-r--r-- | ishtar_common/forms_common.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py index 8964ae57b..a229fe319 100644 --- a/ishtar_common/forms_common.py +++ b/ishtar_common/forms_common.py @@ -30,6 +30,7 @@ from django.core import validators from django.core.mail import send_mail from django.core.exceptions import ObjectDoesNotExist from django.forms.formsets import formset_factory, DELETION_FIELD_NAME +from django.forms.models import BaseModelFormSet from django.template import Context, RequestContext, loader from django.shortcuts import render_to_response from django.utils.safestring import mark_safe @@ -302,6 +303,122 @@ class TownFormSet(FormSet): TownFormset = formset_factory(TownForm, can_delete=True, formset=TownFormSet) TownFormset.form_label = _("Towns") +class MergeFormSet(BaseModelFormSet): + from_key = '' + to_key = '' + def __init__(self, *args, **kwargs): + self._cached_list = [] + super(MergeFormSet, self).__init__(*args, **kwargs) + + def merge(self): + for form in self.initial_forms: + form.merge() + + def initial_form_count(self): + """ + Recopied from django source only get_queryset is changed + """ + if not (self.data or self.files): + return len(self.get_restricted_queryset()) + return super(MergeFormSet, self).initial_form_count() + + def _construct_form(self, i, **kwargs): + """ + Recopied from django source only get_queryset is changed + """ + if self.is_bound and i < self.initial_form_count(): + # Import goes here instead of module-level because importing + # django.db has side effects. + from django.db import connections + pk_key = "%s-%s" % (self.add_prefix(i), self.model._meta.pk.name) + pk = self.data[pk_key] + pk_field = self.model._meta.pk + """pk = pk_field.get_db_prep_lookup('exact', pk, + connection=connections[self.get_queryset().db])""" + pk = self.get_restricted_queryset()[i].pk + if isinstance(pk, list): + pk = pk[0] + kwargs['instance'] = self._existing_object(pk) + if i < self.initial_form_count() and not kwargs.get('instance'): + kwargs['instance'] = self.get_restricted_queryset()[i] + if i >= self.initial_form_count() and self.initial_extra: + # Set initial values for extra forms + try: + kwargs['initial'] = self.initial_extra[i-self.initial_form_count()] + except IndexError: + pass + return super(BaseModelFormSet, self)._construct_form(i, **kwargs) + + def get_restricted_queryset(self): + ''' + Filter (from, to) when (to, from) is already here + ''' + q = self.queryset + if self._cached_list: + return self._cached_list + existing, res = [], [] + # only get one version of each couple + for item in q.all(): + tpl = [getattr(item, self.from_key).pk, + getattr(item, self.to_key).pk] + if tpl not in existing: + res.append(item) + existing.append(list(reversed(tpl))) + self._cached_list = res + return res + +class MergeForm(forms.ModelForm): + id = forms.IntegerField(label=u"", widget=forms.HiddenInput, required=False) + a_is_duplicate_b = forms.BooleanField(required=False) + b_is_duplicate_a = forms.BooleanField(required=False) + not_duplicate = forms.BooleanField(required=False) + + def clean(self): + checked = [True for k in ['a_is_duplicate_b', 'b_is_duplicate_a', + 'not_duplicate'] if self.cleaned_data.get(k)] + if len(checked) > 1: + raise forms.ValidationError(_(u"Only one choice can be checked.")) + return self.cleaned_data + + def merge(self, *args, **kwargs): + try: + to_item = getattr(self.instance, self.TO_KEY) + from_item = getattr(self.instance, self.FROM_KEY) + except ObjectDoesNotExist: + return + if self.cleaned_data.get('a_is_duplicate_b'): + to_item.merge(from_item) + elif self.cleaned_data.get('b_is_duplicate_a'): + from_item.merge(to_item) + elif self.cleaned_data.get('not_duplicate'): + from_item.merge_exclusion.add(to_item) + else: + return + try: + reverse = self.instance.__class__.objects.get( + **{self.TO_KEY:from_item, + self.FROM_KEY:to_item}).delete() + except ObjectDoesNotExist: + pass + self.instance.delete() + +class MergePersonForm(MergeForm): + class Meta: + model = models.Person + fields = [] + + FROM_KEY = 'from_person' + TO_KEY = 'to_person' + +class MergeOrganizationForm(MergeForm): + class Meta: + model = models.Organization + fields = [] + + FROM_KEY = 'from_organization' + TO_KEY = 'to_organization' + + ###################### # Sources management # ###################### |