summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÉtienne Loks <etienne.loks@proxience.com>2015-08-19 15:12:43 +0200
committerÉtienne Loks <etienne.loks@proxience.com>2015-08-19 15:12:43 +0200
commit2c2480a1410c3445572936a70159efda5cc854f4 (patch)
tree840ab617f2927fec8143f6005cfd2d498d1c738f
parent032ac535ce0de17e7b92d9ba7207d49d8f3e21c6 (diff)
downloadIshtar-2c2480a1410c3445572936a70159efda5cc854f4.tar.bz2
Ishtar-2c2480a1410c3445572936a70159efda5cc854f4.zip
Archaeological files: change planning service management
-rw-r--r--archaeological_context_records/forms.py12
-rw-r--r--archaeological_context_records/views.py1
-rw-r--r--archaeological_files/forms.py456
-rw-r--r--archaeological_files/models.py15
-rw-r--r--archaeological_files/views.py4
-rw-r--r--archaeological_files_pdl/forms.py43
-rw-r--r--archaeological_files_pdl/templates/ishtar/wizard/wizard_planningservice.html38
-rw-r--r--archaeological_files_pdl/views.py114
-rw-r--r--archaeological_files_pdl/wizards.py3
-rw-r--r--archaeological_finds/forms.py16
-rw-r--r--archaeological_finds/views.py44
-rw-r--r--archaeological_operations/forms.py6
-rw-r--r--ishtar_common/forms.py63
-rw-r--r--ishtar_common/forms_common.py268
-rw-r--r--ishtar_common/templates/blocks/JQueryAutocomplete.js21
-rw-r--r--ishtar_common/templatetags/replace_underscore.py1
-rw-r--r--ishtar_common/urls.py188
-rw-r--r--ishtar_common/views.py496
-rw-r--r--ishtar_common/widgets.py178
-rw-r--r--ishtar_common/wizards.py168
20 files changed, 1201 insertions, 934 deletions
diff --git a/archaeological_context_records/forms.py b/archaeological_context_records/forms.py
index 34f1a5101..2a9071f64 100644
--- a/archaeological_context_records/forms.py
+++ b/archaeological_context_records/forms.py
@@ -20,14 +20,12 @@
"""
Context records forms definitions
"""
-import datetime
from itertools import groupby
from django import forms
from django.conf import settings
from django.core import validators
-from django.core.exceptions import ObjectDoesNotExist
-from django.db.models import Max
+from django.forms.formsets import formset_factory
from django.utils.translation import ugettext_lazy as _
from ishtar_common.models import valid_id
@@ -35,12 +33,12 @@ from archaeological_operations.models import Period, Parcel, Operation
import models
from ishtar_common import widgets
-from ishtar_common.forms import FinalForm, FinalForm, FormSet, \
- formset_factory, get_now, reverse_lazy, get_form_selection, TableSelect
-from ishtar_common.forms_common import get_town_field, SourceForm, \
- SourceSelect, AuthorFormset
+from ishtar_common.forms import FinalForm, FormSet, \
+ reverse_lazy, get_form_selection, TableSelect
+from ishtar_common.forms_common import get_town_field, SourceSelect
from archaeological_operations.forms import OperationSelect, ParcelField
+
class RecordSelect(TableSelect):
label = forms.CharField(label=_(u"ID"), max_length=100)
parcel__town = get_town_field()
diff --git a/archaeological_context_records/views.py b/archaeological_context_records/views.py
index 73e1cd7b3..526f5aca6 100644
--- a/archaeological_context_records/views.py
+++ b/archaeological_context_records/views.py
@@ -21,6 +21,7 @@ from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
+from ishtar_common.forms_common import AuthorFormset, SourceForm
from ishtar_common.views import get_item, show_item, revert_item
from ishtar_common.wizards import SearchWizard
from wizards import *
diff --git a/archaeological_files/forms.py b/archaeological_files/forms.py
index 5e7229eab..4bde6f97e 100644
--- a/archaeological_files/forms.py
+++ b/archaeological_files/forms.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -25,31 +25,27 @@ import datetime
from django import forms
from django.conf import settings
from django.core import validators
-from django.core.exceptions import ObjectDoesNotExist
-from django.db.models import Max
-from django.shortcuts import render_to_response
-from django.template import RequestContext
from django.utils.translation import ugettext_lazy as _
from django.utils.safestring import mark_safe
-from ishtar_common.models import Person, PersonType, Town, Organization, \
- OrganizationType, valid_id, is_unique, Department
+from ishtar_common.models import Person, PersonType, Organization, \
+ OrganizationType, valid_id, Department
from archaeological_operations.models import ActType, AdministrativeAct, \
- OperationType
+ OperationType
import models
-from ishtar_common.forms import FinalForm, FormSet, ClosingDateFormSelection, \
- formset_factory, get_now, reverse_lazy, TableSelect
-from ishtar_common.forms_common import get_town_field, get_person_field
+from ishtar_common.forms import FinalForm, get_now, reverse_lazy, TableSelect
+from ishtar_common.forms_common import get_town_field
from archaeological_operations.forms import AdministrativeActOpeForm, \
- AdministrativeActOpeFormSelection, FinalAdministrativeActDeleteForm, \
+ AdministrativeActOpeFormSelection, \
ParcelField, SLICING, HEAD_SCIENTIST, SRA_AGENT
from ishtar_common import widgets
GENERAL_CONTRACTOR, created = PersonType.objects.get_or_create(
- txt_idx='general_contractor')
+ txt_idx='general_contractor')
GENERAL_CONTRACTOR_ORGA, created = OrganizationType.objects.get_or_create(
- txt_idx='general_contractor')
+ txt_idx='general_contractor')
+
class FileSelect(TableSelect):
year = forms.IntegerField(label=_("Year"))
@@ -63,33 +59,33 @@ class FileSelect(TableSelect):
parcel = ParcelField(label=_("Parcel (section/number)"))
end_date = forms.NullBooleanField(label=_(u"Is active?"))
general_contractor = forms.IntegerField(
- label=_(u"General contractor"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=[GENERAL_CONTRACTOR.pk]),
- associated_model=Person),
- validators=[valid_id(Person)])
+ label=_(u"General contractor"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-person',
+ args=[GENERAL_CONTRACTOR.pk]),
+ associated_model=Person),
+ validators=[valid_id(Person)])
general_contractor__attached_to = forms.IntegerField(
- label=_(u"Organization of general contractor"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization',
- args=[GENERAL_CONTRACTOR_ORGA.pk]),
- associated_model=Organization),
- validators=[valid_id(Organization)])
+ label=_(u"Organization of general contractor"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-organization',
+ args=[GENERAL_CONTRACTOR_ORGA.pk]),
+ associated_model=Organization),
+ validators=[valid_id(Organization)])
in_charge = forms.IntegerField(
- label=_(u"In charge"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=[SRA_AGENT.pk]),
- associated_model=Person),
- validators=[valid_id(Person)])
+ label=_(u"In charge"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-person',
+ args=[SRA_AGENT.pk]),
+ associated_model=Person),
+ validators=[valid_id(Person)])
history_creator = forms.IntegerField(
- label=_(u"Created by"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=['0', 'user']),
- associated_model=Person),
- validators=[valid_id(Person)])
+ label=_(u"Created by"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-person',
+ args=['0', 'user']),
+ associated_model=Person),
+ validators=[valid_id(Person)])
permit_reference = forms.CharField(max_length=200,
label=_("Permit reference"))
@@ -107,14 +103,18 @@ class FileSelect(TableSelect):
ids.append('parcel_1')
return ids
+
class FileFormSelection(forms.Form):
form_label = _("Archaeological file search")
- associated_models = {'pk':models.File}
- currents = {'pk':models.File}
- pk = forms.IntegerField(label="", required=False,
- widget=widgets.JQueryJqGrid(reverse_lazy('get-file'),
- FileSelect, models.File, source_full=reverse_lazy('get-file-full')),
- validators=[valid_id(models.File)])
+ associated_models = {'pk': models.File}
+ currents = {'pk': models.File}
+ pk = forms.IntegerField(
+ label="", required=False,
+ widget=widgets.JQueryJqGrid(
+ reverse_lazy('get-file'),
+ FileSelect, models.File,
+ source_full=reverse_lazy('get-file-full')),
+ validators=[valid_id(models.File)])
def clean(self):
cleaned_data = self.cleaned_data
@@ -122,24 +122,25 @@ class FileFormSelection(forms.Form):
raise forms.ValidationError(_(u"You should select a file."))
return cleaned_data
-DATE_SOURCE = (('creation',_(u"Creation date")),
- ("reception",_(u"Reception date")))
+DATE_SOURCE = (('creation', _(u"Creation date")),
+ ("reception", _(u"Reception date")))
+
class DashboardForm(forms.Form):
- slicing = forms.ChoiceField(label=_("Slicing"), choices=SLICING,
- required=False)
- department_detail = forms.BooleanField(label=_("Department detail"),
- required=False)
- date_source = forms.ChoiceField(label=_("Date get from"),
- choices=DATE_SOURCE, required=False)
- file_type = forms.ChoiceField(label=_("File type"), choices=[],
- required=False)
- saisine_type = forms.ChoiceField(label=_("Saisine type"), choices=[],
- required=False)
- after = forms.DateField(label=_(u"Date after"),
- widget=widgets.JQueryDate, required=False)
- before = forms.DateField(label=_(u"Date before"),
- widget=widgets.JQueryDate, required=False)
+ slicing = forms.ChoiceField(
+ label=_("Slicing"), choices=SLICING, required=False)
+ department_detail = forms.BooleanField(
+ label=_("Department detail"), required=False)
+ date_source = forms.ChoiceField(
+ label=_("Date get from"), choices=DATE_SOURCE, required=False)
+ file_type = forms.ChoiceField(
+ label=_("File type"), choices=[], required=False)
+ saisine_type = forms.ChoiceField(
+ label=_("Saisine type"), choices=[], required=False)
+ after = forms.DateField(
+ label=_(u"Date after"), widget=widgets.JQueryDate, required=False)
+ before = forms.DateField(
+ label=_(u"Date before"), widget=widgets.JQueryDate, required=False)
def __init__(self, *args, **kwargs):
if 'prefix' not in kwargs:
@@ -150,7 +151,7 @@ class DashboardForm(forms.Form):
def get_show_detail(self):
return hasattr(self, 'cleaned_data') and \
- self.cleaned_data.get('department_detail')
+ self.cleaned_data.get('department_detail')
def get_date_source(self):
date_source = 'creation'
@@ -174,40 +175,43 @@ class DashboardForm(forms.Form):
fltr[date_source+'_date__lte'] = self.cleaned_data['before']
return fltr
+
class FileFormGeneral(forms.Form):
form_label = _("General")
- associated_models = {'in_charge':Person,
- 'related_file':models.File,
- 'file_type':models.FileType}
- in_charge = forms.IntegerField(label=_("Person in charge"),
- widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-person',
- args=[SRA_AGENT.pk]),
- limit={'person_types':[SRA_AGENT.pk]},
- associated_model=Person, new=True),
+ associated_models = {'in_charge': Person,
+ 'related_file': models.File,
+ 'file_type': models.FileType}
+ in_charge = forms.IntegerField(
+ label=_("Person in charge"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-person', args=[SRA_AGENT.pk]),
+ limit={'person_types': [SRA_AGENT.pk]},
+ associated_model=Person, new=True),
validators=[valid_id(Person)])
year = forms.IntegerField(label=_("Year"),
- initial=lambda:datetime.datetime.now().year,
+ initial=lambda: datetime.datetime.now().year,
validators=[validators.MinValueValidator(1900),
validators.MaxValueValidator(2100)])
- numeric_reference = forms.IntegerField(label=_("Numeric reference"),
- widget=forms.HiddenInput, required=False)
- internal_reference = forms.CharField(label=_(u"Other reference"),
- max_length=60, required=False)
+ numeric_reference = forms.IntegerField(
+ label=_("Numeric reference"), widget=forms.HiddenInput, required=False)
+ internal_reference = forms.CharField(
+ label=_(u"Other reference"), max_length=60, required=False)
name = forms.CharField(label=_(u"Name"), required=False, max_length=100)
creation_date = forms.DateField(label=_(u"Creation date"),
initial=get_now, widget=widgets.JQueryDate)
file_type = forms.ChoiceField(label=_("File type"), choices=[])
- related_file = forms.IntegerField(label=_("Related file"), required=False,
- widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-file'),
- associated_model=models.File),
- validators=[valid_id(models.File)])
+ related_file = forms.IntegerField(
+ label=_("Related file"), required=False,
+ widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-file'),
+ associated_model=models.File),
+ validators=[valid_id(models.File)])
comment = forms.CharField(label=_(u"Comment"), widget=forms.Textarea,
required=False)
- total_surface = forms.IntegerField(required=False,
- widget=widgets.AreaWidget,
- label=_(u"Total surface (m²)"),
- validators=[validators.MinValueValidator(0),
- validators.MaxValueValidator(999999999)])
+ total_surface = forms.IntegerField(
+ required=False, widget=widgets.AreaWidget,
+ label=_(u"Total surface (m²)"),
+ validators=[validators.MinValueValidator(0),
+ validators.MaxValueValidator(999999999)])
address = forms.CharField(label=_(u"Main address"), widget=forms.Textarea)
address_complement = forms.CharField(label=_(u"Main address - complement"),
required=False)
@@ -216,19 +220,21 @@ class FileFormGeneral(forms.Form):
super(FileFormGeneral, self).__init__(*args, **kwargs)
self.fields['file_type'].choices = models.FileType.get_types()
self.fields['file_type'].help_text = models.FileType.get_help()
- q = models.File.objects.filter(internal_reference__isnull=False
- ).exclude(internal_reference='').order_by('-pk')
+ q = models.File.objects\
+ .filter(internal_reference__isnull=False)\
+ .exclude(internal_reference='').order_by('-pk')
if q.count():
lbl = self.fields['internal_reference'].label
lbl += _(u"<br/>(last recorded: %s)") % (
- q.all()[0].internal_reference)
+ q.all()[0].internal_reference)
self.fields['internal_reference'].label = mark_safe(lbl)
+
class FileFormGeneralRO(FileFormGeneral):
- year = forms.IntegerField(label=_(u"Year"),
- widget=forms.TextInput(attrs={'readonly':True}))
- numeric_reference = forms.IntegerField(label=_(u"Numeric reference"),
- widget=forms.TextInput())
+ year = forms.IntegerField(
+ label=_(u"Year"), widget=forms.TextInput(attrs={'readonly': True}))
+ numeric_reference = forms.IntegerField(
+ label=_(u"Numeric reference"), widget=forms.TextInput())
id = forms.IntegerField(' ', widget=forms.HiddenInput, required=False)
def clean(self):
@@ -236,123 +242,136 @@ class FileFormGeneralRO(FileFormGeneral):
year = cleaned_data.get('year')
pk = cleaned_data.get('id')
numeric_reference = cleaned_data.get('numeric_reference')
- q = models.File.objects.filter(year=year,
- numeric_reference=numeric_reference
- ).exclude(pk=pk)
+ q = models.File.objects\
+ .filter(year=year, numeric_reference=numeric_reference)\
+ .exclude(pk=pk)
if numeric_reference and q.count():
raise forms.ValidationError(
- _(u"Another file with this numeric id exists."))
+ _(u"Another file with this numeric id exists."))
return cleaned_data
RESPONSIBLE_PLANNING_SERVICE, created = PersonType.objects.get_or_create(
- txt_idx='responsible_planning_service')
+ txt_idx='responsible_planning_service')
RESPONSIBLE_PLANNING_SERVICE_ORGA, created = \
- OrganizationType.objects.get_or_create(
- txt_idx='planning_service')
+ OrganizationType.objects.get_or_create(txt_idx='planning_service')
+
+
class FileFormPreventive(forms.Form):
form_label = _(u"Preventive informations")
- associated_models = {'general_contractor':Person,
- 'saisine_type':models.SaisineType,
- 'permit_type':models.PermitType,
- 'responsible_town_planning_service':Person}
- general_contractor = forms.IntegerField(label=_(u"General contractor"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=[PersonType.objects.get(txt_idx='general_contractor').pk]),
- limit={'person_types':
- [PersonType.objects.get(txt_idx='general_contractor').pk]},
- associated_model=Person, new=True),
- validators=[valid_id(Person)])
- responsible_town_planning_service = forms.IntegerField(required=False,
- label=_(u"Responsible for town planning service"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=[RESPONSIBLE_PLANNING_SERVICE.pk]),
- limit={'person_types':
- [RESPONSIBLE_PLANNING_SERVICE.pk]},
- associated_model=Person, new=True),
- validators=[valid_id(Person)])
+ associated_models = {'general_contractor': Person,
+ 'saisine_type': models.SaisineType,
+ 'permit_type': models.PermitType,
+ 'responsible_town_planning_service': Person}
+ general_contractor = forms.IntegerField(
+ label=_(u"General contractor"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-person',
+ args=[PersonType.objects.get(txt_idx='general_contractor').pk]
+ ),
+ limit={'person_types': [
+ PersonType.objects.get(txt_idx='general_contractor').pk]},
+ associated_model=Person, new=True),
+ validators=[valid_id(Person)])
+ responsible_town_planning_service = forms.IntegerField(
+ required=False,
+ label=_(u"Responsible for town planning service"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-person',
+ args=[RESPONSIBLE_PLANNING_SERVICE.pk]
+ ),
+ limit={'person_types': [
+ RESPONSIBLE_PLANNING_SERVICE.pk]},
+ associated_model=Person, new=True),
+ validators=[valid_id(Person)])
permit_type = forms.ChoiceField(label=_(u"Permit type"), required=False,
choices=[])
- permit_reference = forms.CharField(label=_(u"Permit reference"),
- required=False, validators=[validators.MaxLengthValidator(60)])
- total_developed_surface = forms.IntegerField(widget=widgets.AreaWidget,
- label=_(u"Total developed surface (m²)"),
- required=False, validators=[validators.MinValueValidator(0),
- validators.MaxValueValidator(999999999)])
+ permit_reference = forms.CharField(
+ label=_(u"Permit reference"), required=False,
+ validators=[validators.MaxLengthValidator(60)])
+ total_developed_surface = forms.IntegerField(
+ widget=widgets.AreaWidget, label=_(u"Total developed surface (m²)"),
+ required=False, validators=[validators.MinValueValidator(0),
+ validators.MaxValueValidator(999999999)])
if settings.COUNTRY == 'fr':
saisine_type = forms.ChoiceField(label=_(u"Saisine type"),
choices=[])
- reception_date = forms.DateField(label=_(u"Reception date"),
- initial=get_now, widget=widgets.JQueryDate)
+ reception_date = forms.DateField(
+ label=_(u"Reception date"), initial=get_now, widget=widgets.JQueryDate)
+
def __init__(self, *args, **kwargs):
super(FileFormPreventive, self).__init__(*args, **kwargs)
self.fields['saisine_type'].choices = models.SaisineType.get_types()
self.fields['saisine_type'].help_text = models.SaisineType.get_help()
self.fields['permit_type'].choices = models.PermitType.get_types(
- default='NP')
+ default='NP')
self.fields['permit_type'].help_text = models.PermitType.get_help()
+
class FileFormResearch(forms.Form):
form_label = _("Research archaeology")
base_model = 'department'
- associated_models = {'scientist':Person,
- 'requested_operation_type':OperationType,
- 'organization':Organization,
- 'department':Department}
+ associated_models = {'scientist': Person,
+ 'requested_operation_type': OperationType,
+ 'organization': Organization,
+ 'department': Department}
department = widgets.MultipleAutocompleteField(
- model=Department,
- label=_("Departments"),
- required=False)
+ model=Department,
+ label=_("Departments"),
+ required=False)
scientist = forms.IntegerField(
- widget=widgets.JQueryAutoComplete(reverse_lazy('autocomplete-person',
- args=["_".join(
- [unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)])]),
- limit={'person_types':
- [unicode(HEAD_SCIENTIST.pk),
- unicode(SRA_AGENT.pk)]},
- associated_model=Person, new=True), label=_(u"Scientist in charge"))
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-person',
+ args=["_".join([unicode(HEAD_SCIENTIST.pk),
+ unicode(SRA_AGENT.pk)])]),
+ limit={'person_types': [unicode(HEAD_SCIENTIST.pk),
+ unicode(SRA_AGENT.pk)]},
+ associated_model=Person, new=True),
+ label=_(u"Scientist in charge"))
requested_operation_type = forms.ChoiceField(
- label=_(u"Requested operation type"),
- choices=[])
- organization = forms.IntegerField(label=_(u"Lead organization"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization'),
- associated_model=Organization, new=True),
- validators=[valid_id(Organization)], required=False)
+ label=_(u"Requested operation type"), choices=[])
+ organization = forms.IntegerField(
+ label=_(u"Lead organization"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-organization'),
+ associated_model=Organization, new=True),
+ validators=[valid_id(Organization)], required=False)
if settings.COUNTRY == 'fr':
cira_advised = forms.NullBooleanField(label=u"Passage en CIRA",
required=False)
- research_comment = forms.CharField(label=_(u"Comment"),
- widget=forms.Textarea, required=False)
+ research_comment = forms.CharField(
+ label=_(u"Comment"), widget=forms.Textarea, required=False)
if settings.COUNTRY == 'fr':
mh_register = forms.NullBooleanField(
- label=u"Sur Monument Historique classé",
- required=False)
+ label=u"Sur Monument Historique classé", required=False)
mh_listing = forms.NullBooleanField(
- label=u"Sur Monument Historique inscrit",
- required=False)
- classified_area = forms.NullBooleanField(label=_(u"Classified area"),
- required=False)
- protected_area = forms.NullBooleanField(label=_(u"Protected area"),
- required=False)
+ label=u"Sur Monument Historique inscrit", required=False)
+ classified_area = forms.NullBooleanField(
+ label=_(u"Classified area"), required=False)
+ protected_area = forms.NullBooleanField(
+ label=_(u"Protected area"), required=False)
+
def __init__(self, *args, **kwargs):
super(FileFormResearch, self).__init__(*args, **kwargs)
self.fields['requested_operation_type'].choices = \
- OperationType.get_types(dct={"preventive":False})
+ OperationType.get_types(dct={"preventive": False})
self.fields['requested_operation_type'].help_text = \
- OperationType.get_help()
+ OperationType.get_help()
+
class FinalFileClosingForm(FinalForm):
confirm_msg = " "
confirm_end_msg = _(u"Would you like to close this archaeological file?")
+
class FinalFileDeleteForm(FinalForm):
confirm_msg = " "
confirm_end_msg = _(u"Would you like to delete this archaelogical file ?")
+
class AdministrativeActFileModifySelect(TableSelect):
year = forms.IntegerField(label=_("Year"))
index = forms.IntegerField(label=_("Index"))
@@ -363,77 +382,92 @@ class AdministrativeActFileModifySelect(TableSelect):
operation__towns = get_town_field()
def __init__(self, *args, **kwargs):
- super(AdministrativeActFileModifySelect, self).__init__(*args, **kwargs)
+ super(AdministrativeActFileModifySelect, self).__init__(*args,
+ **kwargs)
self.fields['act_type'].choices = ActType.get_types(
- dct={'intented_to':'F'})
+ dct={'intented_to': 'F'})
self.fields['act_type'].help_text = ActType.get_help(
- dct={'intented_to':'F'})
+ dct={'intented_to': 'F'})
+
class AdministrativeActFileSelect(TableSelect):
associated_file__towns = get_town_field()
act_type = forms.ChoiceField(label=_("Act type"), choices=[])
- signature_date_after = forms.DateField(label=_(u"Signature date after"),
- widget=widgets.JQueryDate)
- signature_date_before = forms.DateField(label=_(u"Signature date before"),
- widget=widgets.JQueryDate)
- associated_file__name = forms.CharField(label=_(u"File name"),
- max_length=200)
+ signature_date_after = forms.DateField(
+ label=_(u"Signature date after"), widget=widgets.JQueryDate)
+ signature_date_before = forms.DateField(
+ label=_(u"Signature date before"), widget=widgets.JQueryDate)
+ associated_file__name = forms.CharField(
+ label=_(u"File name"), max_length=200)
associated_file__general_contractor = forms.IntegerField(
- label=_(u"General contractor"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
- args=[PersonType.objects.get(txt_idx='general_contractor').pk]),
+ label=_(u"General contractor"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-person',
+ args=[
+ PersonType.objects.get(txt_idx='general_contractor').pk]),
associated_model=Person),
- validators=[valid_id(Person)])
+ validators=[valid_id(Person)])
associated_file__general_contractor__attached_to = forms.IntegerField(
- label=_(u"Organization of general contractor"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization',
+ label=_(u"Organization of general contractor"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-organization',
args=[GENERAL_CONTRACTOR_ORGA.pk]),
- associated_model=Organization),
- validators=[valid_id(Organization)])
+ associated_model=Organization),
+ validators=[valid_id(Organization)])
associated_file__numeric_reference = forms.IntegerField(
- label=_("Numeric reference"))
+ label=_("Numeric reference"))
associated_file__year = forms.IntegerField(label=_("Year"))
- associated_file__internal_reference = forms.CharField(max_length=200,
- label=_("Other reference"))
+ associated_file__internal_reference = forms.CharField(
+ max_length=200, label=_("Other reference"))
associated_file__in_charge = forms.IntegerField(
- label=_(u"In charge"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
+ label=_(u"In charge"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-person',
args=[SRA_AGENT.pk]),
- associated_model=Person),
- validators=[valid_id(Person)])
- associated_file__permit_reference = forms.CharField(max_length=200,
- label=_("Permit reference"))
+ associated_model=Person),
+ validators=[valid_id(Person)])
+ associated_file__permit_reference = forms.CharField(
+ max_length=200, label=_("Permit reference"))
history_creator = forms.IntegerField(
- label=_(u"Created by"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-person',
+ label=_(u"Created by"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy(
+ 'autocomplete-person',
args=['0', 'user']),
- associated_model=Person),
- validators=[valid_id(Person)])
+ associated_model=Person),
+ validators=[valid_id(Person)])
def __init__(self, *args, **kwargs):
super(AdministrativeActFileSelect, self).__init__(*args, **kwargs)
self.fields['act_type'].choices = ActType.get_types(
- dct={'intented_to':'F'})
+ dct={'intented_to': 'F'})
self.fields['act_type'].help_text = ActType.get_help(
- dct={'intented_to':'F'})
+ dct={'intented_to': 'F'})
+
class AdministrativeActFileFormSelection(AdministrativeActOpeFormSelection):
- pk = forms.IntegerField(label="", required=False,
- widget=widgets.JQueryJqGrid(reverse_lazy('get-administrativeactfile'),
- AdministrativeActFileSelect, AdministrativeAct,
- table_cols='TABLE_COLS_FILE'),
- validators=[valid_id(AdministrativeAct)])
-
-class AdministrativeActFileModifyFormSelection(AdministrativeActOpeFormSelection):
- pk = forms.IntegerField(label="", required=False,
- widget=widgets.JQueryJqGrid(reverse_lazy('get-administrativeactfile'),
- AdministrativeActFileModifySelect, AdministrativeAct,
- table_cols='TABLE_COLS_FILE'),
- validators=[valid_id(AdministrativeAct)])
+ pk = forms.IntegerField(
+ label="", required=False,
+ widget=widgets.JQueryJqGrid(
+ reverse_lazy('get-administrativeactfile'),
+ AdministrativeActFileSelect, AdministrativeAct,
+ table_cols='TABLE_COLS_FILE'),
+ validators=[valid_id(AdministrativeAct)])
+
+
+class AdministrativeActFileModifyFormSelection(
+ AdministrativeActOpeFormSelection):
+ pk = forms.IntegerField(
+ label="", required=False,
+ widget=widgets.JQueryJqGrid(
+ reverse_lazy('get-administrativeactfile'),
+ AdministrativeActFileModifySelect, AdministrativeAct,
+ table_cols='TABLE_COLS_FILE'),
+ validators=[valid_id(AdministrativeAct)])
+
class AdministrativeActFileForm(AdministrativeActOpeForm):
act_type = forms.ChoiceField(label=_(u"Act type"), choices=[])
@@ -441,6 +475,6 @@ class AdministrativeActFileForm(AdministrativeActOpeForm):
def __init__(self, *args, **kwargs):
super(AdministrativeActFileForm, self).__init__(*args, **kwargs)
self.fields['act_type'].choices = ActType.get_types(
- dct={'intented_to':'F'})
+ dct={'intented_to': 'F'})
self.fields['act_type'].help_text = ActType.get_help(
- dct={'intented_to':'F'})
+ dct={'intented_to': 'F'})
diff --git a/archaeological_files/models.py b/archaeological_files/models.py
index f79de4f98..a7b23564d 100644
--- a/archaeological_files/models.py
+++ b/archaeological_files/models.py
@@ -359,13 +359,23 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem,
def update_planning_service(self):
if not self.responsible_town_planning_service or \
- self.responsible_town_planning_service.attached_to \
- == self.planning_service:
+ not self.responsible_town_planning_service.attached_to or \
+ self.planning_service:
return False
self.planning_service = \
self.responsible_town_planning_service.attached_to
return True
+ def update_resp_planning_service(self):
+ if not self.responsible_town_planning_service or \
+ self.responsible_town_planning_service.attached_to or \
+ not self.planning_service:
+ return False
+ self.responsible_town_planning_service.attached_to = \
+ self.planning_service
+ self.responsible_town_planning_service.save()
+ return True
+
def update_raw_general_contractor(self):
if (self.raw_general_contractor and not
self.general_contractor) or \
@@ -395,6 +405,7 @@ class File(BaseHistorizedItem, OwnPerms, ValueGetter, ShortMenuItem,
self.towns.add(self.main_town)
updated = self.update_raw_town_planning_service()
updated += self.update_planning_service()
+ self.update_resp_planning_service()
updated += self.update_raw_general_contractor()
updated += self.update_corpo_general_contractor()
if updated:
diff --git a/archaeological_files/views.py b/archaeological_files/views.py
index fd0507295..686578933 100644
--- a/archaeological_files/views.py
+++ b/archaeological_files/views.py
@@ -38,7 +38,9 @@ from archaeological_operations.wizards import AdministrativeActDeletionWizard, \
from wizards import *
from ishtar_common.forms_common import TownFormset
-from archaeological_operations.forms import ParcelFormSet
+from archaeological_operations.forms import ParcelFormSet, \
+ FinalAdministrativeActDeleteForm
+from ishtar_common.forms import ClosingDateFormSelection
from forms import *
diff --git a/archaeological_files_pdl/forms.py b/archaeological_files_pdl/forms.py
index 393f53b8c..a0c5037e7 100644
--- a/archaeological_files_pdl/forms.py
+++ b/archaeological_files_pdl/forms.py
@@ -230,25 +230,44 @@ class FileFormGeneralContractor(PersonOrgaForm):
label=" ", widget=forms.HiddenInput, required=False)
-class FileFormPlanningService(PersonOrgaForm):
+class FileFormPlanningService(forms.Form):
form_label = _(u"Town planning service")
associated_models = {'responsible_town_planning_service': models.Person,
'planning_service': models.Organization}
reference_number = forms.IntegerField(label=_(u"File reference"),
required=False)
- PERSON_FIELD = 'responsible_town_planning_service'
- PERSON_TYPE = RESPONSIBLE_PLANNING_SERVICE
- PERSON_LABEL = _(u"Responsible town planning service")
- ORGA_FIELD = 'planning_service'
- ORGA_TYPE = RESPONSIBLE_PLANNING_SERVICE_ORGA
- ORGA_LABEL = _(u"Planning service")
-
- # default initialisation before dynamic
+ planning_service = forms.IntegerField(
+ label=_("Planning service"),
+ required=False,
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-organization',
+ args=[RESPONSIBLE_PLANNING_SERVICE_ORGA.pk]),
+ limit={
+ 'organization_type': [RESPONSIBLE_PLANNING_SERVICE_ORGA.pk]
+ },
+ associated_model=models.Organization,
+ new=True),
+ validators=[valid_id(models.Organization)]
+ )
responsible_town_planning_service = forms.IntegerField(
- label=" ", widget=forms.HiddenInput, required=False)
- planning_service = forms.IntegerField(label=" ", widget=forms.HiddenInput,
- required=False)
+ label=_(u"In charge"),
+ required=False,
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-person',
+ args=[RESPONSIBLE_PLANNING_SERVICE.pk]),
+ associated_model=Person,
+ limit={'person_types': [RESPONSIBLE_PLANNING_SERVICE.pk]},
+ dynamic_limit=['planning_service'],
+ url_new='new-person-noorga',
+ new=True),
+ validators=[valid_id(Person)]
+ )
+
+ def is_valid(self, *args, **kwargs):
+ c = super(FileFormPlanningService, self).is_valid(*args, **kwargs)
+ print(self.cleaned_data)
+ return c
class FileFormInstruction(forms.Form):
diff --git a/archaeological_files_pdl/templates/ishtar/wizard/wizard_planningservice.html b/archaeological_files_pdl/templates/ishtar/wizard/wizard_planningservice.html
index 6fd9eef71..85a1156aa 100644
--- a/archaeological_files_pdl/templates/ishtar/wizard/wizard_planningservice.html
+++ b/archaeological_files_pdl/templates/ishtar/wizard/wizard_planningservice.html
@@ -1,22 +1,44 @@
-{% extends "ishtar/wizard/wizard_person_orga.html" %}
+{% extends "ishtar/wizard/default_wizard.html" %}
+{% load i18n range table_form %}
+{% block wizard_form %}
+<form action="." method="post" name='wizard'{% if wizard.form.file_upload %} enctype="multipart/form-data"{% endif %}>{% csrf_token %}
+<div class='form'>
+{% if wizard.form.media %}{{ wizard.form.media }}{% endif %}
+{{ wizard.management_form }}
+
+<table>
+ {% if wizard.form.non_field_errors %}<tr class='errors'>
+ <td colspan='3'>{{wizard.form.non_field_errors}}</td>
+ </tr>{%endif%}
-{% block corporation %}
<tr class='required'>
<th>{{ wizard.form.planning_service.label_tag }}</th>
<td> {{ wizard.form.planning_service.errors }}{{wizard.form.planning_service|safe}}</td>
</tr>
-{% endblock %}
-
-{% block natural %}
- <tr class='required'>
+ <tr>
<th>{{ wizard.form.responsible_town_planning_service.label_tag }}</th>
<td> {{ wizard.form.responsible_town_planning_service.errors }}{{wizard.form.responsible_town_planning_service|safe}}</td>
</tr>
-{% endblock %}
+</table>
+
-{% block otherfields %}
+<div>
+<table>
<tr class='required'>
<th>{{ wizard.form.reference_number.label_tag }}</th>
<td> {{ wizard.form.reference_number.errors }}{{wizard.form.reference_number|safe}}</td>
</tr>
+</table>
+</div>
+
+<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />
+{{ previous_fields|safe }}
+{% block "validation_bar" %}
+{% include 'ishtar/wizard/validation_bar.html' %}
+{% endblock %}
+</div>
+</form>
{% endblock %}
+
+
+
diff --git a/archaeological_files_pdl/views.py b/archaeological_files_pdl/views.py
index bcb1c0211..8305bdab7 100644
--- a/archaeological_files_pdl/views.py
+++ b/archaeological_files_pdl/views.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
@@ -22,7 +22,8 @@ from django.utils.translation import ugettext_lazy as _
from archaeological_files_pdl.wizards import FileWizard, FileModificationWizard
from archaeological_operations.wizards import is_preventive, is_not_preventive
-from ishtar_common.views import OrganizationPersonCreate, OrganizationPersonEdit
+from ishtar_common.views import OrganizationPersonCreate, \
+ OrganizationPersonEdit
from archaeological_files_pdl import forms
from archaeological_files import forms as ref_forms
@@ -31,69 +32,68 @@ from archaeological_operations.forms import ParcelFormSet
from archaeological_files import models
-file_creation_wizard_is_preventive = is_preventive('general-file_creation',
- models.FileType, type_key='file_type')
+file_creation_wizard_is_preventive = is_preventive(
+ 'general-file_creation', models.FileType, type_key='file_type')
file_creation_wizard_is_not_preventive = is_not_preventive(
- 'general-file_creation', models.FileType, type_key='file_type')
+ 'general-file_creation', models.FileType, type_key='file_type')
file_creation_wizard = FileWizard.as_view([
- ('general-file_creation', forms.FileFormGeneral),
- ('preventivetype-file_creation', forms.FileFormPreventiveType),
- ('preventiveplanning-file_creation', forms.FileFormPlanning),
- ('researchaddress-file_creation', forms.FileFormResearchAddress),
- ('parcelspdl-file_creation', ParcelFormSet),
- ('generalcontractor-file_creation',
- forms.FileFormGeneralContractor),
- ('planningservice-file_creation',
- forms.FileFormPlanningService),
- ('research-file_creation', ref_forms.FileFormResearch),
- ('instruction-file_creation',
- forms.FileFormInstruction),
- ('final-file_creation', ref_forms.FinalForm)],
- label=_(u"New file"),
- condition_dict={
- 'preventivetype-file_creation':file_creation_wizard_is_preventive,
- 'preventiveplanning-file_creation':file_creation_wizard_is_preventive,
- 'generalcontractor-file_creation':file_creation_wizard_is_preventive,
- 'planningservice-file_creation':file_creation_wizard_is_preventive,
- 'researchaddress-file_creation':file_creation_wizard_is_not_preventive,
- 'research-file_creation':file_creation_wizard_is_not_preventive
- },
- url_name='file_creation',)
-
-file_modification_wizard_is_preventive = is_preventive('general-file_modification',
- models.FileType, type_key='file_type')
+ ('general-file_creation', forms.FileFormGeneral),
+ ('preventivetype-file_creation', forms.FileFormPreventiveType),
+ ('preventiveplanning-file_creation', forms.FileFormPlanning),
+ ('researchaddress-file_creation', forms.FileFormResearchAddress),
+ ('parcelspdl-file_creation', ParcelFormSet),
+ ('generalcontractor-file_creation', forms.FileFormGeneralContractor),
+ ('planningservice-file_creation', forms.FileFormPlanningService),
+ ('research-file_creation', ref_forms.FileFormResearch),
+ ('instruction-file_creation', forms.FileFormInstruction),
+ ('final-file_creation', ref_forms.FinalForm)],
+ label=_(u"New file"),
+ condition_dict={
+ 'preventivetype-file_creation': file_creation_wizard_is_preventive,
+ 'preventiveplanning-file_creation': file_creation_wizard_is_preventive,
+ 'generalcontractor-file_creation': file_creation_wizard_is_preventive,
+ 'planningservice-file_creation': file_creation_wizard_is_preventive,
+ 'researchaddress-file_creation':
+ file_creation_wizard_is_not_preventive,
+ 'research-file_creation': file_creation_wizard_is_not_preventive
+ },
+ url_name='file_creation',)
+
+file_modification_wizard_is_preventive = is_preventive(
+ 'general-file_modification', models.FileType, type_key='file_type')
file_modification_wizard_is_not_preventive = is_not_preventive(
- 'general-file_modification', models.FileType, type_key='file_type')
+ 'general-file_modification', models.FileType, type_key='file_type')
file_modification_wizard = FileModificationWizard.as_view([
- ('selec-file_modification', ref_forms.FileFormSelection),
-
- ('general-file_modification', forms.FileFormGeneral),
- ('preventivetype-file_modification', forms.FileFormPreventiveType),
- ('preventiveplanning-file_modification', forms.FileFormPlanning),
- ('researchaddress-file_modification', forms.FileFormResearchAddress),
- ('parcelspdl-file_modification', ParcelFormSet),
- ('generalcontractor-file_modification',
- forms.FileFormGeneralContractor),
- ('planningservice-file_modification',
- forms.FileFormPlanningService),
- ('research-file_modification', ref_forms.FileFormResearch),
- ('instruction-file_modification',
- forms.FileFormInstruction),
- ('final-file_modification', ref_forms.FinalForm)],
- label=_(u"File modification"),
- condition_dict={
- 'preventivetype-file_modification':file_modification_wizard_is_preventive,
- 'preventiveplanning-file_modification':file_modification_wizard_is_preventive,
- 'generalcontractor-file_modification':file_modification_wizard_is_preventive,
- 'planningservice-file_modification':file_modification_wizard_is_preventive,
- 'researchaddress-file_modification':file_modification_wizard_is_not_preventive,
- 'research-file_modification':file_modification_wizard_is_not_preventive
- },
- url_name='file_modification',)
+ ('selec-file_modification', ref_forms.FileFormSelection),
+ ('general-file_modification', forms.FileFormGeneral),
+ ('preventivetype-file_modification', forms.FileFormPreventiveType),
+ ('preventiveplanning-file_modification', forms.FileFormPlanning),
+ ('researchaddress-file_modification', forms.FileFormResearchAddress),
+ ('parcelspdl-file_modification', ParcelFormSet),
+ ('generalcontractor-file_modification', forms.FileFormGeneralContractor),
+ ('planningservice-file_modification', forms.FileFormPlanningService),
+ ('research-file_modification', ref_forms.FileFormResearch),
+ ('instruction-file_modification', forms.FileFormInstruction),
+ ('final-file_modification', ref_forms.FinalForm)],
+ label=_(u"File modification"),
+ condition_dict={
+ 'preventivetype-file_modification': file_modification_wizard_is_preventive,
+ 'preventiveplanning-file_modification':
+ file_modification_wizard_is_preventive,
+ 'generalcontractor-file_modification':
+ file_modification_wizard_is_preventive,
+ 'planningservice-file_modification':
+ file_modification_wizard_is_preventive,
+ 'researchaddress-file_modification':
+ file_modification_wizard_is_not_preventive,
+ 'research-file_modification': file_modification_wizard_is_not_preventive
+ },
+ url_name='file_modification',)
class TownPlanningEdit(OrganizationPersonEdit):
relative_label = _("File followed by")
+
class TownPlanningCreate(OrganizationPersonCreate):
relative_label = _("File followed by")
diff --git a/archaeological_files_pdl/wizards.py b/archaeological_files_pdl/wizards.py
index c081d13d1..666de8155 100644
--- a/archaeological_files_pdl/wizards.py
+++ b/archaeological_files_pdl/wizards.py
@@ -42,8 +42,7 @@ class FileWizard(BaseFileWizard):
def get_form_kwargs(self, *args, **kwargs):
returned = super(FileWizard, self).get_form_kwargs(*args, **kwargs)
- if args and (args[0].startswith('generalcontractor-') or
- args[0].startswith('planningservice-')):
+ if args and args[0].startswith('generalcontractor-'):
if 'status' in self.request.GET:
returned['status'] = self.request.GET['status']
if args and args[0].startswith('instruction-'):
diff --git a/archaeological_finds/forms.py b/archaeological_finds/forms.py
index 5a3ff4ec1..65a1570d8 100644
--- a/archaeological_finds/forms.py
+++ b/archaeological_finds/forms.py
@@ -20,30 +20,24 @@
"""
Finds forms definitions
"""
-import datetime
from django import forms
from django.conf import settings
from django.core import validators
-from django.core.exceptions import ObjectDoesNotExist
-from django.db.models import Max
-from django.shortcuts import render_to_response
-from django.template import RequestContext
+from django.forms.formsets import formset_factory
from django.utils.safestring import mark_safe
from django.utils.translation import ugettext_lazy as _
from ishtar_common.models import Person, valid_id, valid_ids
-from archaeological_operations.models import Period, OperationType
+from archaeological_operations.models import Period
from archaeological_context_records.models import DatingType, DatingQuality
from archaeological_warehouse.models import Warehouse
import models
from ishtar_common import widgets
-from ishtar_common.forms import FinalForm, FormSet, FloatField, \
- formset_factory, get_now, get_form_selection, reverse_lazy, TableSelect
-from ishtar_common.forms_common import get_town_field, \
- SourceForm, SourceSelect, SourceDeletionForm, AuthorFormset
-from archaeological_context_records.forms import RecordFormSelection
+from ishtar_common.forms import FormSet, FloatField, \
+ get_form_selection, reverse_lazy, TableSelect
+from ishtar_common.forms_common import get_town_field, SourceSelect
class FindForm(forms.Form):
diff --git a/archaeological_finds/views.py b/archaeological_finds/views.py
index b5a3debce..63a173edb 100644
--- a/archaeological_finds/views.py
+++ b/archaeological_finds/views.py
@@ -21,16 +21,23 @@ from django.core.urlresolvers import reverse
from django.shortcuts import redirect
from django.utils.translation import ugettext_lazy as _
+from ishtar_common.forms import FinalForm
+from ishtar_common.forms_common import SourceForm, AuthorFormset, \
+ SourceDeletionForm
+from archaeological_context_records.forms import RecordFormSelection
+
from ishtar_common.views import get_item, show_item, revert_item
from ishtar_common.wizards import SearchWizard
+
from wizards import *
from forms import *
import models
-get_find = get_item(models.Find, 'get_find', 'find',
- bool_fields = ['base_finds__is_isolated'],
- reversed_bool_fields = ['image__isnull'],
- base_request={'downstream_treatment__isnull':True},
+get_find = get_item(
+ models.Find, 'get_find', 'find',
+ bool_fields=['base_finds__is_isolated'],
+ reversed_bool_fields=['image__isnull'],
+ base_request={'downstream_treatment__isnull': True},
extra_request_keys={
'base_finds__context_record__parcel__town':
'base_finds__context_record__parcel__town',
@@ -38,18 +45,19 @@ get_find = get_item(models.Find, 'get_find', 'find',
'base_finds__context_record__operation__year__contains',
'base_finds__context_record__operation__code_patriarche':
'base_finds__context_record__operation__code_patriarche',
- 'dating__period':'dating__period__pk',
+ 'dating__period': 'dating__period__pk',
'base_finds__find__description':
'base_finds__find__description__icontains',
- 'base_finds__is_isolated':'base_finds__is_isolated',
- 'image':'image__isnull'})
-get_findsource = get_item(models.FindSource, 'get_findsource', 'findsource',
+ 'base_finds__is_isolated': 'base_finds__is_isolated',
+ 'image': 'image__isnull'})
+get_findsource = get_item(
+ models.FindSource, 'get_findsource', 'findsource',
extra_request_keys={
'find__context_record__operation__year':
'find__context_record__operation__year',
- 'find__dating__period':'find__dating__period__pk',
- 'find__description':'find__description__icontains',
-})
+ 'find__dating__period': 'find__dating__period__pk',
+ 'find__description': 'find__description__icontains',
+ })
show_find = show_item(models.Find, 'find')
revert_find = revert_item(models.Find)
@@ -74,12 +82,14 @@ find_modification_wizard = FindModificationWizard.as_view([
label=_(u"Find modification"),
url_name='find_modification',)
+
def find_modify(request, pk):
- view = find_modification_wizard(request)
+ # view = find_modification_wizard(request)
FindModificationWizard.session_set_value(
- request, 'selec-find_modification', 'pk', pk, reset=True)
- return redirect(reverse('find_modification',
- kwargs={'step':'find-find_modification'}))
+ request, 'selec-find_modification', 'pk', pk, reset=True)
+ return redirect(
+ reverse('find_modification',
+ kwargs={'step': 'find-find_modification'}))
find_source_creation_wizard = FindSourceWizard.as_view([
@@ -116,8 +126,8 @@ treatment_creation_wizard = TreatmentWizard.as_view([
condition_dict={
'selecfind-treatment_creation':
check_treatment('basetreatment-treatment_creation',
- 'treatment_type', not_type_list=['physical_grouping',
- 'packaging']),
+ 'treatment_type', not_type_list=['physical_grouping',
+ 'packaging']),
'multiselecfinds-treatment_creation':
check_treatment('basetreatment-treatment_creation',
'treatment_type', ['physical_grouping',
diff --git a/archaeological_operations/forms.py b/archaeological_operations/forms.py
index b1f2e053b..27f8bae08 100644
--- a/archaeological_operations/forms.py
+++ b/archaeological_operations/forms.py
@@ -27,7 +27,9 @@ from django import forms
from django.conf import settings
from django.core import validators
from django.db.models import Max
-from django.forms.formsets import DELETION_FIELD_NAME, TOTAL_FORM_COUNT
+
+from django.forms.formsets import formset_factory, DELETION_FIELD_NAME, \
+ TOTAL_FORM_COUNT
from django.utils.translation import ugettext_lazy as _, pgettext_lazy
from django.utils.safestring import mark_safe
@@ -45,7 +47,7 @@ import models
from widgets import ParcelWidget, SelectParcelWidget
from ishtar_common import widgets
-from ishtar_common.forms import FinalForm, FormSet, formset_factory, get_now, \
+from ishtar_common.forms import FinalForm, FormSet, get_now, \
reverse_lazy, get_form_selection, TableSelect
from ishtar_common.forms_common import TownFormSet, SourceForm, SourceSelect, \
get_town_field
diff --git a/ishtar_common/forms.py b/ishtar_common/forms.py
index e6f21ae5b..a5abdddcd 100644
--- a/ishtar_common/forms.py
+++ b/ishtar_common/forms.py
@@ -22,27 +22,18 @@ Forms definition
"""
import datetime
import re
-from itertools import groupby
from django import forms
-from django.conf import settings
-from django.contrib.auth.models import User
-from django.contrib.sites.models import Site
from django.core.urlresolvers import reverse
from django.core import validators
-from django.core.exceptions import ObjectDoesNotExist
-from django.core.mail import send_mail
-from django.db.models import Max
-from django.forms.formsets import formset_factory, BaseFormSet, \
- DELETION_FIELD_NAME
-from django.shortcuts import render_to_response
-from django.template import Context, RequestContext, loader
+from django.forms.formsets import BaseFormSet, DELETION_FIELD_NAME
from django.utils import formats
from django.utils.functional import lazy
from django.utils.translation import ugettext_lazy as _
# from formwizard.forms import NamedUrlSessionFormWizard
+
class NamedUrlSessionFormWizard(forms.Form):
def __init__(self, form_list, condition_list={}, url_name=''):
self.form_list = dict(form_list)
@@ -59,8 +50,11 @@ import widgets
reverse_lazy = lazy(reverse, unicode)
regexp_name = re.compile(r"^[,:/\w\-'\"() \&\[\]@]+$", re.UNICODE)
-name_validator = validators.RegexValidator(regexp_name,
-_(u"Enter a valid name consisting of letters, spaces and hyphens."), 'invalid')
+name_validator = validators.RegexValidator(
+ regexp_name,
+ _(u"Enter a valid name consisting of letters, spaces and hyphens."),
+ 'invalid')
+
class FloatField(forms.FloatField):
"""
@@ -71,14 +65,17 @@ class FloatField(forms.FloatField):
value = value.replace(',', '.').replace('%', '')
return super(FloatField, self).clean(value)
+
class FinalForm(forms.Form):
final = True
form_label = _(u"Confirm")
+
class FinalDeleteForm(FinalForm):
confirm_msg = " "
confirm_end_msg = _(u"Are you sure you want to delete?")
+
class FormSet(BaseFormSet):
def check_duplicate(self, key_names, error_msg=""):
"""Check for duplicate items in the formset"""
@@ -91,7 +88,8 @@ class FormSet(BaseFormSet):
form = self.forms[i]
if not form.is_valid():
continue
- item = [key_name in form.cleaned_data and form.cleaned_data[key_name]
+ item = [key_name in form.cleaned_data and
+ form.cleaned_data[key_name]
for key_name in key_names]
if not [v for v in item if v]:
continue
@@ -104,6 +102,7 @@ class FormSet(BaseFormSet):
form.fields[DELETION_FIELD_NAME].label = ''
form.fields[DELETION_FIELD_NAME].widget = widgets.DeleteWidget()
+
class TableSelect(forms.Form):
def __init__(self, *args, **kwargs):
super(TableSelect, self).__init__(*args, **kwargs)
@@ -113,19 +112,23 @@ class TableSelect(forms.Form):
def get_input_ids(self):
return self.fields.keys()
+
def get_now():
format = formats.get_format('DATE_INPUT_FORMATS')[0]
value = datetime.datetime.now().strftime(format)
return value
+
class ClosingDateFormSelection(forms.Form):
form_label = _("Closing date")
end_date = forms.DateField(label=_(u"Closing date"),
widget=widgets.JQueryDate)
-def get_form_selection(class_name, label, key, model, base_form, get_url,
- not_selected_error=_(u"You should select an item."), new=False,
- new_message=_(u"Add a new item")):
+
+def get_form_selection(
+ class_name, label, key, model, base_form, get_url,
+ not_selected_error=_(u"You should select an item."), new=False,
+ new_message=_(u"Add a new item")):
"""
Generate a class selection form
class_name -- name of the class
@@ -137,15 +140,17 @@ def get_form_selection(class_name, label, key, model, base_form, get_url,
new -- can add new items
new_message -- message of link to add new items
"""
- attrs = {'_main_key':key,
- '_not_selected_error':not_selected_error,
- 'form_label':label,
- 'associated_models':{key:model},
- 'currents':{key:model},}
- attrs[key] = forms.IntegerField(label="", required=False,
+ attrs = {'_main_key': key,
+ '_not_selected_error': not_selected_error,
+ 'form_label': label,
+ 'associated_models': {key: model},
+ 'currents': {key: model}}
+ attrs[key] = forms.IntegerField(
+ label="", required=False,
validators=[models.valid_id(model)],
widget=widgets.JQueryJqGrid(reverse_lazy(get_url), base_form, model,
new=new, new_message=new_message))
+
def clean(self):
cleaned_data = self.cleaned_data
if self._main_key not in cleaned_data \
@@ -155,19 +160,21 @@ def get_form_selection(class_name, label, key, model, base_form, get_url,
attrs['clean'] = clean
return type(class_name, (forms.Form,), attrs)
+
class DocumentGenerationForm(forms.Form):
"""
Form to generate document by choosing the template
"""
- _associated_model = None # ex: AdministrativeAct
- _associated_object_name = '' # ex: 'archaeological_operations.models.AdministrativeAct'
+ _associated_model = None # ex: AdministrativeAct
+ # ex: 'archaeological_operations.models.AdministrativeAct'
+ _associated_object_name = ''
document_template = forms.ChoiceField(label=_("Template"), choices=[])
def __init__(self, *args, **kwargs):
super(DocumentGenerationForm, self).__init__(*args, **kwargs)
self.fields['document_template'].choices = \
- models.DocumentTemplate.get_tuples(
- dct={'associated_object_name':self._associated_object_name})
+ models.DocumentTemplate.get_tuples(
+ dct={'associated_object_name': self._associated_object_name})
def save(self, object_pk):
try:
@@ -176,7 +183,7 @@ class DocumentGenerationForm(forms.Form):
return
try:
template = models.DocumentTemplate.objects.get(
- pk=self.cleaned_data.get('document_template'))
+ pk=self.cleaned_data.get('document_template'))
except models.DocumentTemplate.DoesNotExist:
return
return template.publish(c_object)
diff --git a/ishtar_common/forms_common.py b/ishtar_common/forms_common.py
index 509b9fbc5..b2aa565bb 100644
--- a/ishtar_common/forms_common.py
+++ b/ishtar_common/forms_common.py
@@ -20,19 +20,14 @@
"""
Administrative forms definitions: manage accounts and persons
"""
-import datetime
from django import forms
from django.conf import settings
from django.contrib.auth.models import User
-from django.contrib.sites.models import Site
from django.core import validators
-from django.core.exceptions import ObjectDoesNotExist, ValidationError
-from django.core.mail import send_mail
-from django.forms.formsets import formset_factory, DELETION_FIELD_NAME
+from django.core.exceptions import ObjectDoesNotExist
+from django.forms.formsets import formset_factory
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
from django.utils.translation import ugettext_lazy as _
@@ -40,27 +35,33 @@ import models
import widgets
from forms import FinalForm, FormSet, reverse_lazy, name_validator, TableSelect
+
def get_town_field(label=_(u"Town"), required=True):
- help_text = _(u"<p>Type name, department code and/or postal code of the "
- u"town you would like to select. The search is insensitive to case.</p>\n"
- u"<p>Only the first twenty results are displayed but specifying the "
- u"department code is generally sufficient to get the appropriate result.</p>"
- u"\n<p class='example'>For instance type \"saint denis 93\" for getting "
- u"the french town Saint-Denis in the Seine-Saint-Denis department.</p>")
+ help_text = _(
+ u"<p>Type name, department code and/or postal code of the "
+ u"town you would like to select. The search is insensitive to case."
+ u"</p>\n<p>Only the first twenty results are displayed but specifying "
+ u"the department code is generally sufficient to get the appropriate "
+ u"result.</p>\n<p class='example'>For instance type \"saint denis 93\""
+ u" for getting the french town Saint-Denis in the Seine-Saint-Denis "
+ u"department.</p>")
# !FIXME hard_link, reverse_lazy doen't seem to work with formsets
return forms.IntegerField(
- widget=widgets.JQueryAutoComplete("/" + settings.URL_PATH + \
- 'autocomplete-town', associated_model=models.Town),
- validators=[models.valid_id(models.Town)], label=label,
- help_text=mark_safe(help_text), required=required)
+ widget=widgets.JQueryAutoComplete(
+ "/" + settings.URL_PATH + 'autocomplete-town',
+ associated_model=models.Town),
+ validators=[models.valid_id(models.Town)], label=label,
+ help_text=mark_safe(help_text), required=required)
+
def get_advanced_town_field(label=_(u"Town"), required=True):
# !FIXME hard_link, reverse_lazy doen't seem to work with formsets
return forms.IntegerField(
- widget=widgets.JQueryTown("/" + settings.URL_PATH + \
- 'autocomplete-advanced-town'),
- validators=[models.valid_id(models.Town)], label=label,
- required=required)
+ widget=widgets.JQueryTown(
+ "/" + settings.URL_PATH + 'autocomplete-advanced-town'),
+ validators=[models.valid_id(models.Town)], label=label,
+ required=required)
+
def get_person_field(label=_(u"Person"), required=True, person_types=[]):
# !FIXME hard_link, reverse_lazy doen't seem to work with formsets
@@ -69,12 +70,13 @@ def get_person_field(label=_(u"Person"), required=True, person_types=[]):
if person_types:
person_types = [
unicode(models.PersonType.objects.get(txt_idx=person_type).pk)
- for person_type in person_types]
+ for person_type in person_types]
url += u"/" + u'_'.join(person_types)
widget = widgets.JQueryAutoComplete(url, associated_model=models.Person)
return forms.IntegerField(widget=widget, label=label, required=required,
validators=[models.valid_id(models.Person)])
+
class NewItemForm(forms.Form):
def __init__(self, *args, **kwargs):
self.limits = {}
@@ -97,6 +99,7 @@ class NewItemForm(forms.Form):
if len(new_choices) == 1:
self.fields[key].initial = [new_choices[0][0]]
+
class NewImportForm(forms.ModelForm):
class Meta:
model = models.Import
@@ -106,12 +109,13 @@ class NewImportForm(forms.ModelForm):
self.instance.user = user
return super(NewImportForm, self).save(commit)
+
class TargetKeyForm(forms.ModelForm):
class Meta:
model = models.TargetKey
fields = ('target', 'key', 'value')
widgets = {
- 'key': forms.TextInput(attrs={'readonly':'readonly'}),
+ 'key': forms.TextInput(attrs={'readonly': 'readonly'}),
'value': forms.Select(),
}
@@ -121,7 +125,8 @@ class TargetKeyForm(forms.ModelForm):
if instance and instance.pk:
self.fields['target'].widget.attrs['readonly'] = True
self.fields['key'].widget.attrs['readonly'] = True
- self.fields['value'].widget.choices = list(instance.target.get_choices())
+ self.fields['value'].widget.choices = list(
+ instance.target.get_choices())
self.fields['key'].required = False
self.fields['value'].required = False
@@ -146,11 +151,12 @@ class TargetKeyForm(forms.ModelForm):
self.associated_import = None
self.instance.save()
+
class OrganizationForm(NewItemForm):
form_label = _(u"Organization")
- associated_models = {'organization_type':models.OrganizationType}
- name = forms.CharField(label=_(u"Name"), max_length=300,
- validators=[name_validator])
+ associated_models = {'organization_type': models.OrganizationType}
+ name = forms.CharField(
+ label=_(u"Name"), max_length=300, validators=[name_validator])
organization_type = forms.ChoiceField(label=_(u"Organization type"),
choices=[])
address = forms.CharField(label=_(u"Address"), widget=forms.Textarea,
@@ -170,20 +176,21 @@ class OrganizationForm(NewItemForm):
def __init__(self, *args, **kwargs):
super(OrganizationForm, self).__init__(*args, **kwargs)
self.fields['organization_type'].choices = \
- models.OrganizationType.get_types()
+ models.OrganizationType.get_types()
self.fields['organization_type'].help_text = \
- models.OrganizationType.get_help()
+ models.OrganizationType.get_help()
self.limit_fields()
def save(self, user):
dct = self.cleaned_data
dct['history_modifier'] = user
dct['organization_type'] = models.OrganizationType.objects.get(
- pk=dct['organization_type'])
+ pk=dct['organization_type'])
new_item = models.Organization(**dct)
new_item.save()
return new_item
+
class OrganizationSelect(TableSelect):
name = forms.CharField(label=_(u"Name"), max_length=300)
organization_type = forms.ChoiceField(label=_(u"Type"), choices=[])
@@ -191,56 +198,65 @@ class OrganizationSelect(TableSelect):
def __init__(self, *args, **kwargs):
super(OrganizationSelect, self).__init__(*args, **kwargs)
self.fields['organization_type'].choices = \
- models.OrganizationType.get_types()
+ models.OrganizationType.get_types()
+
class OrganizationFormSelection(forms.Form):
form_label = _(u"Organization search")
- associated_models = {'pk':models.Organization}
- currents = {'pk':models.Organization}
- pk = forms.IntegerField(label="",
- widget=widgets.JQueryJqGrid(reverse_lazy('get-organization'),
- OrganizationSelect, models.Organization),
- validators=[models.valid_id(models.Organization)])
+ associated_models = {'pk': models.Organization}
+ currents = {'pk': models.Organization}
+ pk = forms.IntegerField(
+ label="",
+ widget=widgets.JQueryJqGrid(reverse_lazy('get-organization'),
+ OrganizationSelect, models.Organization),
+ validators=[models.valid_id(models.Organization)])
+
class BaseOrganizationForm(forms.ModelForm):
form_prefix = "orga"
+
class Meta:
model = models.Organization
fields = ['name', 'organization_type', 'address', 'address_complement',
- 'town', 'postal_code',]
+ 'town', 'postal_code']
+
class PersonSelect(TableSelect):
name = forms.CharField(label=_(u"Name"), max_length=30)
surname = forms.CharField(label=_(u"Surname"), max_length=20)
email = forms.CharField(label=_(u"Email"), max_length=75)
person_types = forms.ChoiceField(label=_(u"Type"), choices=[])
- attached_to = forms.IntegerField(label=_("Organization"),
- widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization'),
- associated_model=models.Organization),
- validators=[models.valid_id(models.Organization)])
+ attached_to = forms.IntegerField(
+ label=_("Organization"),
+ widget=widgets.JQueryAutoComplete(
+ reverse_lazy('autocomplete-organization'),
+ associated_model=models.Organization),
+ validators=[models.valid_id(models.Organization)])
def __init__(self, *args, **kwargs):
super(PersonSelect, self).__init__(*args, **kwargs)
self.fields['person_types'].choices = models.PersonType.get_types()
+
class PersonFormSelection(forms.Form):
form_label = _(u"Person search")
- associated_models = {'pk':models.Person}
- currents = {'pk':models.Person}
- pk = forms.IntegerField(label="",
- widget=widgets.JQueryJqGrid(reverse_lazy('get-person'),
- PersonSelect, models.Person),
- validators=[models.valid_id(models.Person)])
+ associated_models = {'pk': models.Person}
+ currents = {'pk': models.Person}
+ pk = forms.IntegerField(
+ label="",
+ widget=widgets.JQueryJqGrid(reverse_lazy('get-person'),
+ PersonSelect, models.Person),
+ validators=[models.valid_id(models.Person)])
+
class SimplePersonForm(NewItemForm):
form_label = _("Identity")
- associated_models = {'attached_to':models.Organization}
+ associated_models = {'attached_to': models.Organization}
title = forms.ChoiceField(label=_("Title"), choices=models.Person.TYPE)
surname = forms.CharField(label=_(u"Surname"), max_length=20,
validators=[name_validator])
name = forms.CharField(label=_(u"Name"), max_length=30,
- validators=[name_validator])
+ validators=[name_validator])
address = forms.CharField(label=_(u"Address"), widget=forms.Textarea,
required=False)
address_complement = forms.CharField(label=_(u"Address complement"),
@@ -254,28 +270,31 @@ class SimplePersonForm(NewItemForm):
phone = forms.CharField(label=_(u"Phone"), max_length=18, required=False)
mobile_phone = forms.CharField(label=_(u"Town"), max_length=18,
required=False)
- attached_to = forms.IntegerField(label=_("Current organization"),
+ attached_to = forms.IntegerField(
+ label=_("Current organization"),
widget=widgets.JQueryAutoComplete(
- reverse_lazy('autocomplete-organization'),
- associated_model=models.Organization, new=True),
+ reverse_lazy('autocomplete-organization'),
+ associated_model=models.Organization, new=True),
validators=[models.valid_id(models.Organization)], required=False)
+
class BasePersonForm(forms.ModelForm):
class Meta:
model = models.Person
fields = ['title', 'name', 'surname', 'address', 'address_complement',
'town', 'postal_code']
+
class BaseOrganizationPersonForm(forms.ModelForm):
class Meta:
model = models.Person
- fields = ['attached_to', 'title', 'name', 'surname',]
- widgets = {'attached_to':widgets.JQueryPersonOrganization(
- reverse_lazy('autocomplete-organization'),
- reverse_lazy('organization_create'),
- model=models.Organization,
- attrs={'hidden':True},
- new=True),
+ fields = ['attached_to', 'title', 'name', 'surname']
+ widgets = {'attached_to': widgets.JQueryPersonOrganization(
+ reverse_lazy('autocomplete-organization'),
+ reverse_lazy('organization_create'),
+ model=models.Organization,
+ attrs={'hidden': True},
+ new=True),
}
def __init__(self, *args, **kwargs):
@@ -293,14 +312,16 @@ class BaseOrganizationPersonForm(forms.ModelForm):
person.save()
return person
+
class PersonForm(SimplePersonForm):
- person_types = forms.MultipleChoiceField(label=_("Person type"),
- choices=[], widget=forms.CheckboxSelectMultiple)
+ person_types = forms.MultipleChoiceField(
+ label=_("Person type"), choices=[],
+ widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
super(PersonForm, self).__init__(*args, **kwargs)
self.fields['person_types'].choices = models.PersonType.get_types(
- empty_first=False)
+ empty_first=False)
self.fields['person_types'].help_text = models.PersonType.get_help()
self.limit_fields()
@@ -309,48 +330,58 @@ class PersonForm(SimplePersonForm):
dct['history_modifier'] = user
if 'attached_to' in dct and dct['attached_to']:
dct['attached_to'] = models.Organization.objects.get(
- pk=dct['attached_to'])
+ pk=dct['attached_to'])
person_types = dct.pop('person_types')
new_item = models.Person.objects.create(**dct)
for pt in person_types:
new_item.person_types.add(pt)
return new_item
+
+class NoOrgaPersonForm(PersonForm):
+ def __init__(self, *args, **kwargs):
+ super(NoOrgaPersonForm, self).__init__(*args, **kwargs)
+ self.fields.pop('attached_to')
+
+
class PersonTypeForm(forms.Form):
form_label = _("Person type")
base_model = 'person_type'
- associated_models = {'person_type':models.PersonType}
- person_type = forms.MultipleChoiceField(label=_("Person type"),
- choices=[], widget=forms.CheckboxSelectMultiple)
+ associated_models = {'person_type': models.PersonType}
+ person_type = forms.MultipleChoiceField(
+ label=_("Person type"), choices=[],
+ widget=forms.CheckboxSelectMultiple)
def __init__(self, *args, **kwargs):
super(PersonTypeForm, self).__init__(*args, **kwargs)
self.fields['person_type'].choices = models.PersonType.get_types(
- empty_first=False)
+ empty_first=False)
self.fields['person_type'].help_text = models.PersonType.get_help()
+
class AccountForm(forms.Form):
form_label = _("Account")
- associated_models = {'pk':models.Person}
- currents = {'pk':models.Person}
- pk = forms.IntegerField(label=u"", widget=forms.HiddenInput, required=False)
+ associated_models = {'pk': models.Person}
+ currents = {'pk': models.Person}
+ pk = forms.IntegerField(label=u"", widget=forms.HiddenInput,
+ required=False)
username = forms.CharField(label=_(u"Account"), max_length=30)
email = forms.CharField(label=_(u"Email"), max_length=75,
validators=[validators.validate_email])
- hidden_password = forms.CharField(label=_(u"New password"), max_length=128,
- widget=forms.PasswordInput, required=False,
- validators=[validators.MinLengthValidator(4)])
+ hidden_password = forms.CharField(
+ label=_(u"New password"), max_length=128, widget=forms.PasswordInput,
+ required=False, validators=[validators.MinLengthValidator(4)])
hidden_password_confirm = forms.CharField(
- label=_(u"New password (confirmation)"), max_length=128,
- widget=forms.PasswordInput, required=False)
+ label=_(u"New password (confirmation)"), max_length=128,
+ widget=forms.PasswordInput, required=False)
def __init__(self, *args, **kwargs):
if 'initial' in kwargs and 'pk' in kwargs['initial']:
try:
person = models.Person.objects.get(pk=kwargs['initial']['pk'])
account = models.IshtarUser.objects.get(person=person)
- kwargs['initial'].update({'username':account.username,
- 'email':account.email})
+ kwargs['initial'].update({'username': account.username,
+ 'email': account.email})
except ObjectDoesNotExist:
pass
return super(AccountForm, self).__init__(*args, **kwargs)
@@ -358,23 +389,25 @@ class AccountForm(forms.Form):
def clean(self):
cleaned_data = self.cleaned_data
password = cleaned_data.get("hidden_password")
- if password and password != cleaned_data.get("hidden_password_confirm"):
+ if password and \
+ password != cleaned_data.get("hidden_password_confirm"):
raise forms.ValidationError(_(u"Your password and confirmation "
u"password do not match."))
if not cleaned_data.get("pk"):
models.is_unique(User, 'username')(cleaned_data.get("username"))
if not password:
- raise forms.ValidationError(_(u"You must provide a correct "\
+ raise forms.ValidationError(_(u"You must provide a correct "
u"password."))
# check username unicity
- usernames = models.IshtarUser.objects.filter(username=
- cleaned_data.get('username'))
+ usernames = models.IshtarUser.objects.filter(
+ username=cleaned_data.get('username'))
if cleaned_data.get('pk'):
usernames.exclude(pk=cleaned_data.get('pk'))
if usernames.count():
raise forms.ValidationError(_(u"This username already exists."))
return cleaned_data
+
class FinalAccountForm(forms.Form):
final = True
form_label = _("Confirm")
@@ -385,12 +418,14 @@ class FinalAccountForm(forms.Form):
self.is_hidden = True
return super(FinalAccountForm, self).__init__(*args, **kwargs)
+
class TownForm(forms.Form):
form_label = _("Towns")
base_model = 'town'
- associated_models = {'town':models.Town}
+ associated_models = {'town': models.Town}
town = get_town_field(required=False)
+
class TownFormSet(FormSet):
def clean(self):
"""Checks that no towns are duplicated."""
@@ -400,9 +435,11 @@ 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)
@@ -426,11 +463,11 @@ class MergeFormSet(BaseModelFormSet):
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
+ # 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,
+ """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):
@@ -441,7 +478,8 @@ class MergeFormSet(BaseModelFormSet):
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()]
+ kwargs['initial'] = \
+ self.initial_extra[i-self.initial_form_count()]
except IndexError:
pass
return super(BaseModelFormSet, self)._construct_form(i, **kwargs)
@@ -464,8 +502,10 @@ class MergeFormSet(BaseModelFormSet):
self._cached_list = res
return res
+
class MergeForm(forms.ModelForm):
- id = forms.IntegerField(label=u"", widget=forms.HiddenInput, required=False)
+ 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)
@@ -492,13 +532,14 @@ class MergeForm(forms.ModelForm):
else:
return
try:
- reverse = self.instance.__class__.objects.get(
- **{self.TO_KEY:from_item,
- self.FROM_KEY:to_item}).delete()
+ 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
@@ -507,6 +548,7 @@ class MergePersonForm(MergeForm):
FROM_KEY = 'from_person'
TO_KEY = 'to_person'
+
class MergeOrganizationForm(MergeForm):
class Meta:
model = models.Organization
@@ -521,12 +563,12 @@ class MergeOrganizationForm(MergeForm):
######################
class SourceForm(forms.Form):
form_label = _(u"Documentation informations")
- associated_models = {'source_type':models.SourceType}
+ associated_models = {'source_type': models.SourceType}
title = forms.CharField(label=_(u"Title"),
validators=[validators.MaxLengthValidator(200)])
source_type = forms.ChoiceField(label=_(u"Source type"), choices=[])
- associated_url = forms.URLField(required=False,
- label=_(u"Numerical ressource (web address)"))
+ associated_url = forms.URLField(
+ required=False, label=_(u"Numerical ressource (web address)"))
receipt_date = forms.DateField(label=_(u"Receipt date"), required=False,
widget=widgets.JQueryDate)
creation_date = forms.DateField(label=_(u"Creation date"), required=False,
@@ -536,12 +578,14 @@ class SourceForm(forms.Form):
super(SourceForm, self).__init__(*args, **kwargs)
self.fields['source_type'].choices = models.SourceType.get_types()
+
class SourceSelect(TableSelect):
authors = forms.IntegerField(
- widget=widgets.JQueryAutoComplete("/" + settings.URL_PATH + \
- 'autocomplete-author', associated_model=models.Author),
- validators=[models.valid_id(models.Author)], label=_(u"Author"),
- required=False)
+ widget=widgets.JQueryAutoComplete(
+ "/" + settings.URL_PATH + 'autocomplete-author',
+ associated_model=models.Author),
+ validators=[models.valid_id(models.Author)], label=_(u"Author"),
+ required=False)
source_type = forms.ChoiceField(label=_("Source type"), choices=[])
@@ -550,6 +594,7 @@ class SourceSelect(TableSelect):
self.fields['source_type'].choices = models.SourceType.get_types()
self.fields['source_type'].help_text = models.SourceType.get_help()
+
class SourceDeletionForm(FinalForm):
confirm_msg = " "
confirm_end_msg = _(u"Would you like to delete this documentation?")
@@ -558,14 +603,16 @@ class SourceDeletionForm(FinalForm):
# Authors management #
######################
+
class AuthorForm(NewItemForm):
form_label = _(u"Author")
- associated_models = {'person':models.Person,
- 'author_type':models.AuthorType}
+ associated_models = {'person': models.Person,
+ 'author_type': models.AuthorType}
person = forms.IntegerField(
- widget=widgets.JQueryAutoComplete("/" + settings.URL_PATH + \
- 'autocomplete-person', associated_model=models.Person, new=True),
- validators=[models.valid_id(models.Person)], label=_(u"Person"))
+ widget=widgets.JQueryAutoComplete(
+ "/" + settings.URL_PATH + 'autocomplete-person',
+ associated_model=models.Person, new=True),
+ validators=[models.valid_id(models.Person)], label=_(u"Person"))
author_type = forms.ChoiceField(label=_(u"Author type"), choices=[])
def __init__(self, *args, **kwargs):
@@ -576,7 +623,7 @@ class AuthorForm(NewItemForm):
def save(self, user):
dct = self.cleaned_data
dct['author_type'] = models.AuthorType.objects.get(
- pk=dct['author_type'])
+ pk=dct['author_type'])
dct['person'] = models.Person.objects.get(pk=dct['person'])
new_item = models.Author(**dct)
new_item.save()
@@ -586,11 +633,13 @@ class AuthorForm(NewItemForm):
class AuthorFormSelection(forms.Form):
form_label = _(u"Author selection")
base_model = 'author'
- associated_models = {'author':models.Author}
+ associated_models = {'author': models.Author}
author = forms.IntegerField(
- widget=widgets.JQueryAutoComplete("/" + settings.URL_PATH + \
- 'autocomplete-author', associated_model=models.Author, new=True),
- validators=[models.valid_id(models.Author)], label=_(u"Author"))
+ widget=widgets.JQueryAutoComplete(
+ "/" + settings.URL_PATH + 'autocomplete-author',
+ associated_model=models.Author, new=True),
+ validators=[models.valid_id(models.Author)], label=_(u"Author"))
+
class AuthorFormSet(FormSet):
def clean(self):
@@ -601,4 +650,3 @@ class AuthorFormSet(FormSet):
AuthorFormset = formset_factory(AuthorFormSelection, can_delete=True,
formset=AuthorFormSet)
AuthorFormset.form_label = _("Authors")
-
diff --git a/ishtar_common/templates/blocks/JQueryAutocomplete.js b/ishtar_common/templates/blocks/JQueryAutocomplete.js
index eb365c38a..038acf1ba 100644
--- a/ishtar_common/templates/blocks/JQueryAutocomplete.js
+++ b/ishtar_common/templates/blocks/JQueryAutocomplete.js
@@ -1,8 +1,13 @@
+{% load replace_underscore %}
+var base_source_{{field_id|replace_underscore}} = {{source}};
+var source_{{field_id|replace_underscore}} = base_source_{{field_id|replace_underscore}};
+
$("#id_select_{{field_id}}").autocomplete({
- source: {{source}},
+ source: source_{{field_id|replace_underscore}},
select: function( event, ui ) {
if(ui.item){
$('#id_{{field_id}}').val(ui.item.id);
+ $('#id_{{field_id}}').change();
} else {
$('#id_{{field_id}}').val(null);
}
@@ -17,3 +22,17 @@ $('#id_select_{{field_id}}').live('click', function(){
$('#id_select_{{field_id}}').val(null);
});
+
+{% if dynamic_limit %}{% for item_id in dynamic_limit %}
+$('#{{item_id}}').change(function(){
+ $("#id_select_{{field_id}}").autocomplete( "option", "source",
+ base_source_{{field_id|replace_underscore}} + $('#{{item_id}}').val()
+ + '/');
+ if ($('#{{item_id}}').val()){
+ $("#id_select_{{field_id}}").prop("disabled", false);
+ } else {
+ $("#id_select_{{field_id}}").prop("disabled", true);
+ }
+});
+$('#{{item_id}}').change();
+{% endfor %}{% endif %}
diff --git a/ishtar_common/templatetags/replace_underscore.py b/ishtar_common/templatetags/replace_underscore.py
index 66931e6fe..d49fcf4fb 100644
--- a/ishtar_common/templatetags/replace_underscore.py
+++ b/ishtar_common/templatetags/replace_underscore.py
@@ -5,6 +5,7 @@ from django.template import Library
register = Library()
+
@register.filter
def replace_underscore(value):
return value.replace('-', '_')
diff --git a/ishtar_common/urls.py b/ishtar_common/urls.py
index bce968b51..eb0fe7ac2 100644
--- a/ishtar_common/urls.py
+++ b/ishtar_common/urls.py
@@ -18,7 +18,7 @@
# See the file COPYING for details.
from django.conf import settings
-from django.conf.urls.defaults import *
+from django.conf.urls.defaults import patterns, include, url
from django.conf.urls.static import static
from menus import menu
@@ -29,53 +29,54 @@ urlpatterns, actions = [], []
# forms
-urlpatterns = patterns('',
- # internationalization
- url(r'^i18n/', include('django.conf.urls.i18n')),
- # General
- url(r'person_search/(?P<step>.+)?$',
- views.person_search_wizard, name='person_search'),
- url(r'person_creation/(?P<step>.+)?$',
- views.person_creation_wizard, name='person_creation'),
- url(r'person_modification/(?P<step>.+)?$',
- views.person_modification_wizard, name='person_modification'),
- url(r'person_deletion/(?P<step>.+)?$',
- views.person_deletion_wizard, name='person_deletion'),
- url(r'^person-edit/$',
- views.PersonCreate.as_view(), name='person_create'),
- url(r'^person-edit/(?P<pk>\d+)$',
- views.PersonEdit.as_view(), name='person_edit'),
- url(r'organization_search/(?P<step>.+)?$',
- views.organization_search_wizard, name='organization_search'),
- url(r'organization_creation/(?P<step>.+)?$',
- views.organization_creation_wizard, name='organization_creation'),
- url(r'organization_modification/(?P<step>.+)?$',
- views.organization_modification_wizard,
- name='organization_modification'),
- url(r'organization_deletion/(?P<step>.+)?$',
- views.organization_deletion_wizard, name='organization_deletion'),
- url(r'organization-edit/$',
- views.OrganizationCreate.as_view(), name='organization_create'),
- url(r'organization-edit/(?P<pk>\d+)$',
- views.OrganizationEdit.as_view(), name='organization_edit'),
- url(r'organization-person-edit/$',
- views.OrganizationPersonCreate.as_view(),
- name='organization_person_create'),
- url(r'organization-person-edit/(?P<pk>\d+)$',
- views.OrganizationPersonEdit.as_view(),
- name='organization_person_edit'),
- url(r'account_management/(?P<step>.+)?$',
- views.account_management_wizard, name='account_management'),
- url(r'^import-new/$', views.NewImportView.as_view(), name='new_import'),
- url(r'^import-list/$', views.ImportListView.as_view(),
- name='current_imports'),
- url(r'^import-list-old/$', views.ImportOldListView.as_view(),
- name='old_imports'),
- url(r'^import-delete/(?P<pk>[0-9]+)/$',
- views.ImportDeleteView.as_view(), name='import_delete'),
- url(r'^import-link-unmatched/(?P<pk>[0-9]+)/$',
- views.ImportLinkView.as_view(), name='import_link_unmatched'),
- )
+urlpatterns = patterns(
+ '',
+ # internationalization
+ url(r'^i18n/', include('django.conf.urls.i18n')),
+ # General
+ url(r'person_search/(?P<step>.+)?$',
+ views.person_search_wizard, name='person_search'),
+ url(r'person_creation/(?P<step>.+)?$',
+ views.person_creation_wizard, name='person_creation'),
+ url(r'person_modification/(?P<step>.+)?$',
+ views.person_modification_wizard, name='person_modification'),
+ url(r'person_deletion/(?P<step>.+)?$',
+ views.person_deletion_wizard, name='person_deletion'),
+ url(r'^person-edit/$',
+ views.PersonCreate.as_view(), name='person_create'),
+ url(r'^person-edit/(?P<pk>\d+)$',
+ views.PersonEdit.as_view(), name='person_edit'),
+ url(r'organization_search/(?P<step>.+)?$',
+ views.organization_search_wizard, name='organization_search'),
+ url(r'organization_creation/(?P<step>.+)?$',
+ views.organization_creation_wizard, name='organization_creation'),
+ url(r'organization_modification/(?P<step>.+)?$',
+ views.organization_modification_wizard,
+ name='organization_modification'),
+ url(r'organization_deletion/(?P<step>.+)?$',
+ views.organization_deletion_wizard, name='organization_deletion'),
+ url(r'organization-edit/$',
+ views.OrganizationCreate.as_view(), name='organization_create'),
+ url(r'organization-edit/(?P<pk>\d+)$',
+ views.OrganizationEdit.as_view(), name='organization_edit'),
+ url(r'organization-person-edit/$',
+ views.OrganizationPersonCreate.as_view(),
+ name='organization_person_create'),
+ url(r'organization-person-edit/(?P<pk>\d+)$',
+ views.OrganizationPersonEdit.as_view(),
+ name='organization_person_edit'),
+ url(r'account_management/(?P<step>.+)?$',
+ views.account_management_wizard, name='account_management'),
+ url(r'^import-new/$', views.NewImportView.as_view(), name='new_import'),
+ url(r'^import-list/$', views.ImportListView.as_view(),
+ name='current_imports'),
+ url(r'^import-list-old/$', views.ImportOldListView.as_view(),
+ name='old_imports'),
+ url(r'^import-delete/(?P<pk>[0-9]+)/$',
+ views.ImportDeleteView.as_view(), name='import_delete'),
+ url(r'^import-link-unmatched/(?P<pk>[0-9]+)/$',
+ views.ImportLinkView.as_view(), name='import_link_unmatched'),
+)
for section in menu.childs:
for menu_item in section.childs:
if hasattr(menu_item, 'childs'):
@@ -86,50 +87,57 @@ for section in menu.childs:
actions = r"|".join(actions)
# other views
-urlpatterns += patterns('ishtar_common.views',
- # General
- url(r'dashboard-main/$', 'dashboard_main',
- name='dashboard-main'),
- url(r'dashboard-main/(?P<item_name>[a-z-]+)/$', 'dashboard_main_detail',
- name='dashboard-main-detail'),
- url(r'update-current-item/$', 'update_current_item',
- name='update-current-item'),
- url(r'new-person/(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',
- 'new_person', name='new-person'),
- url(r'autocomplete-person(?:/([0-9_]+))?/(user)?$', 'autocomplete_person',
- name='autocomplete-person'),
- url(r'get-person/(?P<type>.+)?$', 'get_person',
- name='get-person'),
- url(r'show-person(?:/(?P<pk>.+))?/(?P<type>.+)?$',
- 'show_person', name='show-person'),
- url(r'department-by-state/(?P<state_id>.+)?$', 'department_by_state',
- name='department-by-state'),
- url(r'autocomplete-town/?$', 'autocomplete_town',
- name='autocomplete-town'),
- url(r'autocomplete-advanced-town/(?P<department_id>[0-9]+[ABab]?)?$',
+urlpatterns += patterns(
+ 'ishtar_common.views',
+ # General
+ url(r'dashboard-main/$', 'dashboard_main',
+ name='dashboard-main'),
+ url(r'dashboard-main/(?P<item_name>[a-z-]+)/$', 'dashboard_main_detail',
+ name='dashboard-main-detail'),
+ url(r'update-current-item/$', 'update_current_item',
+ name='update-current-item'),
+ url(r'new-person/(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',
+ 'new_person', name='new-person'),
+ url(r'new-person-noorga/'
+ r'(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',
+ 'new_person_noorga', name='new-person-noorga'),
+ url(r'autocomplete-person(?:/([0-9_]+))?(?:/([0-9_]*))?/(user)?$',
+ 'autocomplete_person', name='autocomplete-person'),
+ url(r'get-person/(?P<type>.+)?$', 'get_person',
+ name='get-person'),
+ url(r'show-person(?:/(?P<pk>.+))?/(?P<type>.+)?$',
+ 'show_person', name='show-person'),
+ url(r'department-by-state/(?P<state_id>.+)?$', 'department_by_state',
+ name='department-by-state'),
+ url(r'autocomplete-town/?$', 'autocomplete_town',
+ name='autocomplete-town'),
+ url(r'autocomplete-advanced-town/(?P<department_id>[0-9]+[ABab]?)?$',
'autocomplete_advanced_town', name='autocomplete-advanced-town'),
- url(r'autocomplete-department/?$', 'autocomplete_department',
- name='autocomplete-department'),
- url(r'new-author/(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',
- 'new_author', name='new-author'),
- url(r'autocomplete-author/$', 'autocomplete_author',
- name='autocomplete-author'),
- url(r'new-organization/(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',
- 'new_organization', name='new-organization'),
- url(r'get-organization/(?P<type>.+)?$', 'get_organization',
- name='get-organization'),
- url(r'show-organization(?:/(?P<pk>.+))?/(?P<type>.+)?$',
- 'show_organization', name='show-organization'),
- url(r'autocomplete-organization/([0-9_]+)?$',
- 'autocomplete_organization', name='autocomplete-organization'),
- url(r'admin-globalvar/', views.GlobalVarEdit.as_view(),
+ url(r'autocomplete-department/?$', 'autocomplete_department',
+ name='autocomplete-department'),
+ url(r'new-author/(?:(?P<parent_name>[^/]+)/)?(?:(?P<limits>[^/]+)/)?$',
+ 'new_author', name='new-author'),
+ url(r'autocomplete-author/$', 'autocomplete_author',
+ name='autocomplete-author'),
+ url(r'new-organization/(?:(?P<parent_name>[^/]+)/)?'
+ r'(?:(?P<limits>[^/]+)/)?$',
+ 'new_organization', name='new-organization'),
+ url(r'get-organization/(?P<type>.+)?$', 'get_organization',
+ name='get-organization'),
+ url(r'show-organization(?:/(?P<pk>.+))?/(?P<type>.+)?$',
+ 'show_organization', name='show-organization'),
+ url(r'autocomplete-organization/([0-9_]+)?$',
+ 'autocomplete_organization', name='autocomplete-organization'),
+ url(r'admin-globalvar/', views.GlobalVarEdit.as_view(),
name='admin-globalvar'),
- url(r'person_merge/(?:(?P<page>\d+)/)?$', 'person_merge', name='person_merge'),
- url(r'organization_merge/(?:(?P<page>\d+)/)?$', 'organization_merge',
- name='organization_merge'),
- url(r'reset/$', 'reset_wizards', name='reset_wizards'),
- url(r'(?P<action_slug>' + actions + r')/$', 'action', name='action'),
+ url(r'person_merge/(?:(?P<page>\d+)/)?$', 'person_merge',
+ name='person_merge'),
+ url(r'organization_merge/(?:(?P<page>\d+)/)?$', 'organization_merge',
+ name='organization_merge'),
+ url(r'reset/$', 'reset_wizards', name='reset_wizards'),
+ url(r'(?P<action_slug>' + actions + r')/$', 'action', name='action'),
)
if settings.DEBUG:
- urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
+ urlpatterns += static(settings.STATIC_URL,
+ document_root=settings.STATIC_ROOT)
diff --git a/ishtar_common/views.py b/ishtar_common/views.py
index 0058821b2..fc8151d8d 100644
--- a/ishtar_common/views.py
+++ b/ishtar_common/views.py
@@ -19,14 +19,14 @@
from tidylib import tidy_document as tidy
-import re
import csv
-import json
+import cStringIO as StringIO
import datetime
+import ho.pisa as pisa
+import json
import optparse
-import cStringIO as StringIO
+import re
from tempfile import NamedTemporaryFile
-import ho.pisa as pisa
import unicodedata
from extra_views import ModelFormSetView
@@ -34,17 +34,17 @@ from extra_views import ModelFormSetView
from django.conf import settings
from django.contrib.auth import logout
from django.contrib.auth.decorators import login_required
-from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse, NoReverseMatch
-from django.db.models import Q, F, ImageField
-from django.forms.models import model_to_dict, modelformset_factory
-from django.http import HttpResponse, Http404, HttpResponseRedirect
+from django.db.models import Q, ImageField
+from django.forms.models import modelformset_factory
+from django.http import HttpResponse, Http404, HttpResponseRedirect, \
+ HttpResponseBadRequest
from django.shortcuts import render_to_response, redirect
from django.template import RequestContext, loader
from django.utils.decorators import method_decorator
from django.utils.translation import ugettext, ugettext_lazy as _
-from django.views.generic import ListView, UpdateView, CreateView
+from django.views.generic import ListView, UpdateView
from django.views.generic.edit import CreateView, DeleteView
from xhtml2odt import xhtml2odt
@@ -56,11 +56,14 @@ from archaeological_operations.forms import DashboardForm as DashboardFormOpe
from ishtar_common.forms import FinalForm, FinalDeleteForm
from ishtar_common import forms_common as forms
from ishtar_common import wizards
+from ishtar_common.models import HistoryError
+
import models
-CSV_OPTIONS = {'delimiter':';', 'quotechar':'"', 'quoting':csv.QUOTE_ALL}
+CSV_OPTIONS = {'delimiter': ';', 'quotechar': '"', 'quoting': csv.QUOTE_ALL}
ENCODING = settings.ENCODING or 'utf-8'
+
def index(request):
"""
Main page
@@ -68,69 +71,70 @@ def index(request):
dct = {}
try:
return render_to_response('index.html', dct,
- context_instance=RequestContext(request))
+ context_instance=RequestContext(request))
except NoReverseMatch:
# probably rights exception (rights revoked)
logout(request)
return render_to_response('index.html', dct,
- context_instance=RequestContext(request))
+ context_instance=RequestContext(request))
+
+person_search_wizard = wizards.SearchWizard.as_view(
+ [('general-person_search', forms.PersonFormSelection)],
+ label=_(u"Person search"),
+ url_name='person_search',)
+
+person_creation_wizard = wizards.PersonWizard.as_view(
+ [('identity-person_creation', forms.SimplePersonForm),
+ ('person_type-person_creation', forms.PersonTypeForm),
+ ('final-person_creation', FinalForm)],
+ label=_(u"New person"),
+ url_name='person_creation')
+
+person_modification_wizard = wizards.PersonModifWizard.as_view(
+ [('selec-person_modification', forms.PersonFormSelection),
+ ('identity-person_modification', forms.SimplePersonForm),
+ ('person_type-person_creation', forms.PersonTypeForm),
+ ('final-person_modification', FinalForm)],
+ label=_(u"Person modification"),
+ url_name='person_modification')
+
+person_deletion_wizard = wizards.PersonDeletionWizard.as_view(
+ [('selec-person_deletion', forms.PersonFormSelection),
+ ('final-person_deletion', FinalDeleteForm)],
+ label=_(u"Person deletion"),
+ url_name='person_deletion',)
+
+organization_search_wizard = wizards.SearchWizard.as_view(
+ [('general-organization_search', forms.OrganizationFormSelection)],
+ label=_(u"Organization search"),
+ url_name='organization_search',)
+
+organization_creation_wizard = wizards.OrganizationWizard.as_view(
+ [('identity-organization_creation', forms.OrganizationForm),
+ ('final-organization_creation', FinalForm)],
+ label=_(u"New organization"),
+ url_name='organization_creation')
+
+organization_modification_wizard = wizards.OrganizationModifWizard.as_view(
+ [('selec-organization_modification', forms.OrganizationFormSelection),
+ ('identity-organization_modification', forms.OrganizationForm),
+ ('final-organization_modification', FinalForm)],
+ label=_(u"Organization modification"),
+ url_name='organization_modification')
+
+organization_deletion_wizard = wizards.OrganizationDeletionWizard.as_view(
+ [('selec-organization_deletion', forms.OrganizationFormSelection),
+ ('final-organization_deletion', FinalDeleteForm)],
+ label=_(u"Organization deletion"),
+ url_name='organization_deletion',)
+
+account_management_wizard = wizards.AccountWizard.as_view(
+ [('selec-account_management', forms.PersonFormSelection),
+ ('account-account_management', forms.AccountForm),
+ ('final-account_management', forms.FinalAccountForm)],
+ label=_(u"Account management"),
+ url_name='account_management',)
-person_search_wizard = wizards.SearchWizard.as_view([
- ('general-person_search', forms.PersonFormSelection)],
- label=_(u"Person search"),
- url_name='person_search',)
-
-person_creation_wizard = wizards.PersonWizard.as_view([
- ('identity-person_creation', forms.SimplePersonForm),
- ('person_type-person_creation', forms.PersonTypeForm),
- ('final-person_creation', FinalForm)],
- label=_(u"New person"),
- url_name='person_creation')
-
-person_modification_wizard = wizards.PersonModifWizard.as_view([
- ('selec-person_modification', forms.PersonFormSelection),
- ('identity-person_modification', forms.SimplePersonForm),
- ('person_type-person_creation', forms.PersonTypeForm),
- ('final-person_modification', FinalForm)],
- label=_(u"Person modification"),
- url_name='person_modification')
-
-person_deletion_wizard = wizards.PersonDeletionWizard.as_view([
- ('selec-person_deletion', forms.PersonFormSelection),
- ('final-person_deletion', FinalDeleteForm)],
- label=_(u"Person deletion"),
- url_name='person_deletion',)
-
-organization_search_wizard = wizards.SearchWizard.as_view([
- ('general-organization_search', forms.OrganizationFormSelection)],
- label=_(u"Organization search"),
- url_name='organization_search',)
-
-organization_creation_wizard = wizards.OrganizationWizard.as_view([
- ('identity-organization_creation', forms.OrganizationForm),
- ('final-organization_creation', FinalForm)],
- label=_(u"New organization"),
- url_name='organization_creation')
-
-organization_modification_wizard = wizards.OrganizationModifWizard.as_view([
- ('selec-organization_modification', forms.OrganizationFormSelection),
- ('identity-organization_modification', forms.OrganizationForm),
- ('final-organization_modification', FinalForm)],
- label=_(u"Organization modification"),
- url_name='organization_modification')
-
-organization_deletion_wizard = wizards.OrganizationDeletionWizard.as_view([
- ('selec-organization_deletion', forms.OrganizationFormSelection),
- ('final-organization_deletion', FinalDeleteForm)],
- label=_(u"Organization deletion"),
- url_name='organization_deletion',)
-
-account_management_wizard = wizards.AccountWizard.as_view([
- ('selec-account_management', forms.PersonFormSelection),
- ('account-account_management', forms.AccountForm),
- ('final-account_management', forms.FinalAccountForm)],
- label=_(u"Account management"),
- url_name='account_management',)
def update_current_item(request):
if not request.is_ajax() and not request.method == 'POST':
@@ -139,15 +143,18 @@ def update_current_item(request):
request.session[request.POST['item']] = request.POST['value']
return HttpResponse('ok')
+
def check_permission(request, action_slug, obj_id=None):
if action_slug not in menu.items:
- #! TODO
+ # TODO
return True
if obj_id:
return menu.items[action_slug].is_available(request.user, obj_id)
return menu.items[action_slug].can_be_available(request.user)
-def autocomplete_person(request, person_types=None, is_ishtar_user=None):
+
+def autocomplete_person(request, person_types=None, attached_to=None,
+ is_ishtar_user=None):
if not request.user.has_perm('ishtar_common.view_person', models.Person) and \
not request.user.has_perm('ishtar_common.view_own_person', models.Person) \
and not request.user.ishtaruser.has_right('person_search'):
@@ -162,9 +169,13 @@ def autocomplete_person(request, person_types=None, is_ishtar_user=None):
return HttpResponseBadRequest()
query = Q()
for q in q.split(' '):
- query = query & (Q(name__icontains=q) | Q(surname__icontains=q) | \
- Q(email__icontains=q) | Q(attached_to__name__icontains=q))
- if person_types and unicode(person_types) != '0':
+ query = query & (Q(name__icontains=q) | Q(surname__icontains=q) |
+ Q(email__icontains=q) |
+ Q(attached_to__name__icontains=q))
+ if attached_to:
+ query = query & Q(attached_to__pk__in=attached_to.split('_'))
+
+ if person_types and unicode(person_types) != '0':
try:
typs = [int(tp) for tp in person_types.split('_') if tp]
typ = models.PersonType.objects.filter(pk__in=typs).all()
@@ -175,48 +186,51 @@ def autocomplete_person(request, person_types=None, is_ishtar_user=None):
query = query & Q(ishtaruser__isnull=False)
limit = 20
persons = models.Person.objects.filter(query)[:limit]
- data = json.dumps([{'id':person.pk, 'value':unicode(person)}
- for person in persons if person])
+ data = json.dumps([{'id': person.pk, 'value': unicode(person)}
+ for person in persons if person])
return HttpResponse(data, mimetype='text/plain')
+
def autocomplete_department(request):
if not request.GET.get('term'):
return HttpResponse(mimetype='text/plain')
q = request.GET.get('term')
- q = unicodedata.normalize("NFKD", q).encode('ascii','ignore')
+ q = unicodedata.normalize("NFKD", q).encode('ascii', 'ignore')
query = Q()
for q in q.split(' '):
extra = (Q(label__icontains=q) | Q(number__istartswith=q))
query = query & extra
limit = 20
departments = models.Department.objects.filter(query)[:limit]
- data = json.dumps([{'id':department.pk, 'value':unicode(department)}
- for department in departments])
+ data = json.dumps([{'id': department.pk, 'value': unicode(department)}
+ for department in departments])
return HttpResponse(data, mimetype='text/plain')
+
def autocomplete_town(request):
if not request.GET.get('term'):
return HttpResponse(mimetype='text/plain')
q = request.GET.get('term')
- q = unicodedata.normalize("NFKD", q).encode('ascii','ignore')
+ q = unicodedata.normalize("NFKD", q).encode('ascii', 'ignore')
query = Q()
for q in q.split(' '):
extra = Q(name__icontains=q)
if settings.COUNTRY == 'fr':
- extra = (extra | Q(numero_insee__istartswith=q) | \
- Q(departement__label__istartswith=q))
+ extra = (extra | Q(numero_insee__istartswith=q) |
+ Q(departement__label__istartswith=q))
query = query & extra
limit = 20
towns = models.Town.objects.filter(query)[:limit]
- data = json.dumps([{'id':town.pk, 'value':unicode(town)}
- for town in towns])
+ data = json.dumps([{'id': town.pk, 'value': unicode(town)}
+ for town in towns])
return HttpResponse(data, mimetype='text/plain')
+
def autocomplete_advanced_town(request, department_id=None, state_id=None):
if not request.GET.get('term'):
return HttpResponse(mimetype='text/plain')
q = request.GET.get('term')
- q = unicodedata.normalize("NFKD", q).encode('ascii','ignore')
+ q = unicodedata.normalize("NFKD", q).encode('ascii', 'ignore')
query = Q()
for q in q.split(' '):
extra = Q(name__icontains=q)
@@ -236,25 +250,24 @@ def autocomplete_advanced_town(request, department_id=None, state_id=None):
val = town.name
if hasattr(town, 'numero_insee'):
val += " (%s)" % town.numero_insee
- result.append({'id':town.pk, 'value':val})
+ result.append({'id': town.pk, 'value': val})
data = json.dumps(result)
return HttpResponse(data, mimetype='text/plain')
+
def department_by_state(request, state_id=''):
if not state_id:
data = []
else:
departments = models.Department.objects.filter(state__number=state_id)
- data = json.dumps([{'id':department.pk, 'number':department.number,
- 'value':unicode(department)}
- for department in departments])
+ data = json.dumps([{'id': department.pk, 'number': department.number,
+ 'value': unicode(department)}
+ for department in departments])
return HttpResponse(data, mimetype='text/plain')
-from types import NoneType
-
def format_val(val):
- if type(val) == NoneType:
+ if val is None:
return u""
if type(val) == bool:
if val:
@@ -267,33 +280,33 @@ HIERARCHIC_LEVELS = 5
HIERARCHIC_FIELDS = ['periods', 'period', 'unit', 'material_type',
'conservatory_state']
PRIVATE_FIELDS = ('id', 'history_modifier', 'order')
+
+
def get_item(model, func_name, default_name, extra_request_keys=[],
- base_request={}, bool_fields=[], reversed_bool_fields=[],
- dated_fields=[], associated_models=[], relative_session_names={},
- specific_perms=[]):
+ base_request={}, bool_fields=[], reversed_bool_fields=[],
+ dated_fields=[], associated_models=[], relative_session_names={},
+ specific_perms=[]):
"""
Generic treatment of tables
"""
def func(request, data_type='json', full=False, **dct):
# check rights
- own = True # more restrictive by default
+ own = True # more restrictive by default
allowed = False
for perm, lbl in model._meta.permissions:
# if not specific any perm is relevant (read right)
if specific_perms and perm not in specific_perms:
continue
if request.user.has_perm(model._meta.app_label + '.' + perm) \
- or (request.user.is_authenticated()
- and request.user.ishtaruser.has_right(perm)):
+ or (request.user.is_authenticated()
+ and request.user.ishtaruser.has_right(perm)):
allowed = True
if "_own_" not in perm:
own = False
- break # max right reach
- EMPTY, mimetype = '', 'text/plain'
+ break # max right reach
+ EMPTY = ''
if 'type' in dct:
data_type = dct.pop('type')
- if data_type == 'csv':
- mimetype = 'text/csv'
if not data_type:
EMPTY = '[]'
data_type = 'json'
@@ -301,18 +314,23 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
return HttpResponse(EMPTY, mimetype='text/plain')
fields = [model._meta.get_field_by_name(k)[0]
for k in model._meta.get_all_field_names()]
- request_keys = dict([(field.name,
- field.name + (hasattr(field, 'rel') and field.rel and '__pk' or ''))
- for field in fields])
+ request_keys = dict([
+ (field.name,
+ field.name + (hasattr(field, 'rel') and field.rel and '__pk'
+ or ''))
+ for field in fields])
for associated_model, key in associated_models:
- associated_fields = [associated_model._meta.get_field_by_name(k)[0]
- for k in associated_model._meta.get_all_field_names()]
- request_keys.update(dict([(key + "__" + field.name,
- key + "__" + field.name + (hasattr(field, 'rel') and
- field.rel and '__pk' or ''))
- for field in associated_fields]))
+ associated_fields = [
+ associated_model._meta.get_field_by_name(k)[0]
+ for k in associated_model._meta.get_all_field_names()]
+ request_keys.update(
+ dict([(key + "__" + field.name,
+ key + "__" + field.name +
+ (hasattr(field, 'rel') and field.rel and '__pk' or ''))
+ for field in associated_fields]))
request_keys.update(extra_request_keys)
- request_items = request.method == 'POST' and request.POST or request.GET
+ request_items = request.method == 'POST' and request.POST \
+ or request.GET
dct = base_request.copy()
and_reqs, or_reqs = [], []
try:
@@ -327,14 +345,15 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if not dct and 'submited' not in request_items:
if default_name in request.session and \
request.session[default_name]:
- dct = {"pk":request.session[default_name]}
+ dct = {"pk": request.session[default_name]}
else:
for name in relative_session_names.keys():
if name in request.session and request.session[name]:
k = relative_session_names[name]
- dct = {k:request.session[name]}
+ dct = {k: request.session[name]}
break
- if (not dct or data_type == 'csv') and func_name in request.session:
+ if (not dct or data_type == 'csv') \
+ and func_name in request.session:
dct = request.session[func_name]
else:
request.session[func_name] = dct
@@ -351,7 +370,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if k.endswith('__isnull') and \
isinstance(c_field, ImageField):
if dct[k]:
- or_reqs.append((k, {k.split('__')[0]+'__exact':''}))
+ or_reqs.append(
+ (k, {k.split('__')[0]+'__exact': ''}))
else:
dct[k.split('__')[0]+'__regex'] = '.{1}.*'
for k in dated_fields:
@@ -362,8 +382,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
items = dct[k].split('/')
assert len(items) == 3
dct[k] = datetime.date(*map(lambda x: int(x),
- reversed(items))
- ).strftime('%Y-%m-%d')
+ reversed(items)))\
+ .strftime('%Y-%m-%d')
except AssertionError:
dct.pop(k)
# manage hierarchic conditions
@@ -374,18 +394,18 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
q = None
for idx, r in enumerate(req):
if not idx:
- q = Q(**{r:val})
+ q = Q(**{r: val})
else:
- q = q | Q(**{r:val})
+ q = q | Q(**{r: val})
and_reqs.append(q)
break
elif req.endswith(k_hr + '__pk'):
val = dct.pop(req)
- reqs = Q(**{req:val})
+ reqs = Q(**{req: val})
req = req[:-2] + '__'
for idx in xrange(HIERARCHIC_LEVELS):
req = req[:-2] + 'parent__pk'
- q = Q(**{req:val})
+ q = Q(**{req: val})
reqs = reqs | q
and_reqs.append(reqs)
break
@@ -405,7 +425,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
# table cols
table_cols = full and [field.name for field in model._meta.fields
if field.name not in PRIVATE_FIELDS] \
- or model.TABLE_COLS
+ or model.TABLE_COLS
# manage sort tables
manual_sort_key = None
order = request_items.get('sord')
@@ -461,14 +481,15 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
for ky in k.split('.'):
new_vals = []
for val in vals:
- if hasattr(val, 'all'): # manage related objects
+ if hasattr(val, 'all'): # manage related objects
val = list(val.all())
for v in val:
new_vals.append(getattr(v, ky))
elif val:
new_vals.append(getattr(val, ky))
vals = new_vals
- if vals and hasattr(vals[0], 'all'): # manage last related objects
+ # manage last related objects
+ if vals and hasattr(vals[0], 'all'):
new_vals = []
for val in vals:
new_vals += list(val.all())
@@ -478,32 +499,33 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
if manual_sort_key:
# +1 because the id is added as a first col
idx_col = table_cols.index(manual_sort_key) + 1
- datas = sorted(datas, key=lambda x:x[idx_col])
+ datas = sorted(datas, key=lambda x: x[idx_col])
if sign == '-':
datas = reversed(datas)
datas = list(datas)[start:end]
- link_template = "<a class='display_details' href='#' onclick='load_window(\"%%s\")'>%s</a>" % \
+ link_template = "<a class='display_details' href='#' "\
+ "onclick='load_window(\"%%s\")'>%s</a>" % \
(unicode(_("Details")))
if data_type == "json":
rows = []
for data in datas:
try:
lnk = link_template % reverse('show-'+default_name,
- args=[data[0], ''])
+ args=[data[0], ''])
except NoReverseMatch:
print '"show-' + default_name + "\" args (" + \
unicode(data[0]) + ") url not available"
lnk = ''
- res = {'id':data[0], 'link':lnk}
+ res = {'id': data[0], 'link': lnk}
for idx, value in enumerate(data[1:]):
if value:
res[table_cols[idx].split('.')[-1]] = value
rows.append(res)
data = json.dumps({
- "records":items_nb,
- "rows":rows,
- "page":page_nb,
- "total":(items_nb/row_nb + 1) if row_nb else items_nb,
+ "records": items_nb,
+ "rows": rows,
+ "page": page_nb,
+ "total": (items_nb/row_nb + 1) if row_nb else items_nb,
})
return HttpResponse(data, mimetype='text/plain')
elif data_type == "csv":
@@ -511,7 +533,8 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
n = datetime.datetime.now()
filename = u'%s_%s.csv' % (default_name,
n.strftime('%Y%m%d-%H%M%S'))
- response['Content-Disposition'] = 'attachment; filename=%s'%filename
+ response['Content-Disposition'] = 'attachment; filename=%s'\
+ % filename
writer = csv.writer(response, **CSV_OPTIONS)
col_names = []
for field_name in table_cols:
@@ -529,6 +552,7 @@ def get_item(model, func_name, default_name, extra_request_keys=[],
return func
+
def show_item(model, name, extra_dct=None):
def func(request, pk, **dct):
try:
@@ -540,15 +564,15 @@ def show_item(model, name, extra_dct=None):
).split('/')[:-2]) + u"/"
dct['current_window_url'] = url_name
date = 'date' in dct and dct.pop('date')
- dct['window_id'] = "%s-%d-%s" % (name, item.pk,
- datetime.datetime.now().strftime('%M%s'))
+ dct['window_id'] = "%s-%d-%s" % (
+ name, item.pk, datetime.datetime.now().strftime('%M%s'))
if hasattr(item, 'history'):
if date:
try:
date = datetime.datetime.strptime(date,
'%Y-%m-%dT%H:%M:%S.%f')
item = item.get_previous(date=date)
- assert item != None
+ assert item is not None
except (ValueError, AssertionError):
return HttpResponse(None, mimetype='text/plain')
dct['previous'] = item._previous
@@ -565,7 +589,6 @@ def show_item(model, name, extra_dct=None):
dct.update(extra_dct(request, item))
context_instance = RequestContext(request)
context_instance.update(dct)
- n = datetime.datetime.now()
filename = ""
if hasattr(item, 'history_object'):
filename = item.history_object.associated_filename
@@ -575,9 +598,9 @@ def show_item(model, name, extra_dct=None):
tpl = loader.get_template('ishtar/sheet_%s.html' % name)
content = tpl.render(context_instance)
try:
- tidy_options = {'output-xhtml':1, 'indent':1,
- 'tidy-mark':0, 'doctype':'auto',
- 'add-xml-decl':1, 'wrap':1}
+ tidy_options = {'output-xhtml': 1, 'indent': 1,
+ 'tidy-mark': 0, 'doctype': 'auto',
+ 'add-xml-decl': 1, 'wrap': 1}
html, errors = tidy(content, options=tidy_options)
html = html.encode('utf-8').replace("&nbsp;", "&#160;")
html = re.sub('<pre([^>]*)>\n', '<pre\\1>', html)
@@ -602,12 +625,12 @@ def show_item(model, name, extra_dct=None):
odtfile.open()
odtfile.import_xhtml(html)
odtfile = odtfile.save()
- except xhtml2odt.ODTExportError, ex:
+ except xhtml2odt.ODTExportError:
return HttpResponse(content, content_type="application/xhtml")
response = HttpResponse(
- mimetype='application/vnd.oasis.opendocument.text')
+ mimetype='application/vnd.oasis.opendocument.text')
response['Content-Disposition'] = 'attachment; filename=%s.odt' % \
- filename
+ filename
response.write(odtfile)
return response
elif doc_type == 'pdf':
@@ -621,7 +644,7 @@ def show_item(model, name, extra_dct=None):
response = HttpResponse(result.getvalue(),
mimetype='application/pdf')
response['Content-Disposition'] = 'attachment; filename=%s.pdf' % \
- filename
+ filename
if not pdf.err:
return response
return HttpResponse(content, content_type="application/xhtml")
@@ -631,6 +654,7 @@ def show_item(model, name, extra_dct=None):
return HttpResponse(content, content_type="application/xhtml")
return func
+
def revert_item(model):
def func(request, pk, date, **dct):
try:
@@ -642,11 +666,12 @@ def revert_item(model):
return HttpResponse("True", mimetype='text/plain')
return func
+
def autocomplete_organization(request, orga_type=None):
if (not request.user.has_perm('ishtar_common.view_organization',
- models.Organization) and \
- not request.user.has_perm('ishtar_common.view_own_organization',
- models.Organization)
+ models.Organization) and
+ not request.user.has_perm('ishtar_common.view_own_organization',
+ models.Organization)
and not request.user.ishtaruser.has_right('person_search')):
return HttpResponse(mimetype='text/plain')
if not request.GET.get('term'):
@@ -665,14 +690,15 @@ def autocomplete_organization(request, orga_type=None):
pass
limit = 15
organizations = models.Organization.objects.filter(query)[:limit]
- data = json.dumps([{'id':org.pk, 'value':unicode(org)}
- for org in organizations])
+ data = json.dumps([{'id': org.pk, 'value': unicode(org)}
+ for org in organizations])
return HttpResponse(data, mimetype='text/plain')
+
def autocomplete_author(request):
if not request.user.has_perm('ishtar_common.view_author', models.Author)\
and not request.user.has_perm('ishtar_common.view_own_author',
- models.Author) :
+ models.Author):
return HttpResponse(mimetype='text/plain')
if not request.GET.get('term'):
return HttpResponse(mimetype='text/plain')
@@ -680,23 +706,24 @@ def autocomplete_author(request):
query = Q()
for q in q.split(' '):
extra = Q(person__name__icontains=q) | \
- Q(person__surname__icontains=q) | \
- Q(person__email__icontains=q) | \
- Q(author_type__label__icontains=q)
+ Q(person__surname__icontains=q) | \
+ Q(person__email__icontains=q) | \
+ Q(author_type__label__icontains=q)
query = query & extra
limit = 15
authors = models.Author.objects.filter(query)[:limit]
- data = json.dumps([{'id':author.pk, 'value':unicode(author)}
- for author in authors])
+ data = json.dumps([{'id': author.pk, 'value': unicode(author)}
+ for author in authors])
return HttpResponse(data, mimetype='text/plain')
+
def new_item(model, frm):
def func(request, parent_name, limits=''):
model_name = model._meta.object_name
if not check_permission(request, 'add_'+model_name.lower()):
not_permitted_msg = ugettext(u"Operation not permitted.")
return HttpResponse(not_permitted_msg)
- dct = {'title':unicode(_(u'New %s' % model_name.lower()))}
+ dct = {'title': unicode(_(u'New %s' % model_name.lower()))}
if request.method == 'POST':
dct['form'] = frm(request.POST, limits=limits)
if dct['form'].is_valid():
@@ -708,8 +735,9 @@ def new_item(model, frm):
if dct['parent_pk'] and '_select_' in dct['parent_pk']:
parents = dct['parent_pk'].split('_')
dct['parent_pk'] = "_".join([parents[0]] + parents[2:])
- return render_to_response('window.html', dct,
- context_instance=RequestContext(request))
+ return render_to_response(
+ 'window.html', dct,
+ context_instance=RequestContext(request))
else:
dct['form'] = frm(limits=limits)
return render_to_response('window.html', dct,
@@ -717,24 +745,28 @@ def new_item(model, frm):
return func
new_person = new_item(models.Person, forms.PersonForm)
+new_person_noorga = new_item(models.Person, forms.NoOrgaPersonForm)
new_organization = new_item(models.Organization, forms.OrganizationForm)
show_organization = show_item(models.Organization, 'organization')
-get_organization = get_item(models.Organization,
- 'get_organization', 'organization',
- extra_request_keys={
- 'name':'name__icontains',
- 'organization_type':'organization_type__pk__in',
- },)
+get_organization = get_item(
+ models.Organization,
+ 'get_organization', 'organization',
+ extra_request_keys={
+ 'name': 'name__icontains',
+ 'organization_type': 'organization_type__pk__in',
+ })
new_author = new_item(models.Author, forms.AuthorForm)
show_person = show_item(models.Person, 'person')
-get_person = get_item(models.Person,
- 'get_person', 'person',
- extra_request_keys={
- 'name':'name__icontains',
- 'surname':'surname__icontains',
- 'attached_to':'attached_to__pk',
- 'person_types':'person_types__pk__in',
- },)
+get_person = get_item(
+ models.Person,
+ 'get_person', 'person',
+ extra_request_keys={
+ 'name': 'name__icontains',
+ 'surname': 'surname__icontains',
+ 'attached_to': 'attached_to__pk',
+ 'person_types': 'person_types__pk__in',
+ })
+
def action(request, action_slug, obj_id=None, *args, **kwargs):
"""
@@ -744,7 +776,6 @@ def action(request, action_slug, obj_id=None, *args, **kwargs):
not_permitted_msg = ugettext(u"Operation not permitted.")
return HttpResponse(not_permitted_msg)
request.session['CURRENT_ACTION'] = action_slug
- associated_wizard = action_slug + '_wizard'
dct = {}
globals_dct = globals()
if action_slug in globals_dct:
@@ -752,6 +783,7 @@ def action(request, action_slug, obj_id=None, *args, **kwargs):
return render_to_response('index.html', dct,
context_instance=RequestContext(request))
+
def dashboard_main(request, dct, obj_id=None, *args, **kwargs):
"""
Main dashboard
@@ -764,9 +796,9 @@ def dashboard_main(request, dct, obj_id=None, *args, **kwargs):
app_list.append((_(u"Context records"), 'contextrecords'))
if 'archaeological_finds' in settings.INSTALLED_APPS:
app_list.append((_(u"Finds"), 'finds'))
- dct = {'app_list':app_list}
+ dct = {'app_list': app_list}
return render_to_response('ishtar/dashboards/dashboard_main.html', dct,
- context_instance=RequestContext(request))
+ context_instance=RequestContext(request))
DASHBOARD_FORMS = {}
if 'archaeological_files' in settings.INSTALLED_APPS:
@@ -775,20 +807,21 @@ if 'archaeological_files' in settings.INSTALLED_APPS:
DASHBOARD_FORMS['operations'] = DashboardFormOpe
+
def dashboard_main_detail(request, item_name):
"""
Specific tab of the main dashboard
"""
if item_name == 'users':
- dct = {'ishtar_users':models.UserDashboard()}
+ dct = {'ishtar_users': models.UserDashboard()}
return render_to_response(
- 'ishtar/dashboards/dashboard_main_detail_users.html',
- dct, context_instance=RequestContext(request))
+ 'ishtar/dashboards/dashboard_main_detail_users.html',
+ dct, context_instance=RequestContext(request))
form = None
- slicing, date_source, fltr, show_detail = 'year', None, {}, False
- if (item_name == 'files' and \
- 'archaeological_files' in settings.INSTALLED_APPS) \
- or item_name == 'operations':
+ slicing, date_source, fltr, show_detail = 'year', None, {}, False
+ if (item_name == 'files' and
+ 'archaeological_files' in settings.INSTALLED_APPS) \
+ or item_name == 'operations':
slicing = 'month'
if item_name in DASHBOARD_FORMS:
if request.method == 'POST':
@@ -803,16 +836,16 @@ def dashboard_main_detail(request, item_name):
else:
form = DASHBOARD_FORMS[item_name]()
lbl, dashboard = None, None
- if (item_name == 'files' and \
- 'archaeological_files' in settings.INSTALLED_APPS) \
- or item_name == 'operations':
- dashboard_kwargs = {'slice':slicing, 'fltr':fltr,
- 'show_detail':show_detail}
+ if (item_name == 'files' and
+ 'archaeological_files' in settings.INSTALLED_APPS) \
+ or item_name == 'operations':
+ dashboard_kwargs = {'slice': slicing, 'fltr': fltr,
+ 'show_detail': show_detail}
# date_source is only relevant when the form has set one
if date_source:
dashboard_kwargs['date_source'] = date_source
if item_name == 'files' and \
- 'archaeological_files' in settings.INSTALLED_APPS:
+ 'archaeological_files' in settings.INSTALLED_APPS:
from archaeological_files.models import File
lbl, dashboard = (_(u"Archaeological files"),
models.Dashboard(File, **dashboard_kwargs))
@@ -821,26 +854,29 @@ def dashboard_main_detail(request, item_name):
lbl, dashboard = (_(u"Operations"),
models.Dashboard(Operation, **dashboard_kwargs))
if item_name == 'contextrecords' and \
- 'archaeological_context_records' in settings.INSTALLED_APPS:
+ 'archaeological_context_records' in settings.INSTALLED_APPS:
from archaeological_context_records.models import ContextRecord
- lbl, dashboard = (_(u"Context records"), models.Dashboard(ContextRecord,
- slice=slicing, fltr=fltr))
+ lbl, dashboard = (
+ _(u"Context records"),
+ models.Dashboard(ContextRecord, slice=slicing, fltr=fltr))
if item_name == 'finds' and \
- 'archaeological_finds' in settings.INSTALLED_APPS:
+ 'archaeological_finds' in settings.INSTALLED_APPS:
from archaeological_finds.models import Find
lbl, dashboard = (_(u"Finds"), models.Dashboard(Find,
- slice=slicing, fltr=fltr))
+ slice=slicing,
+ fltr=fltr))
if not lbl:
raise Http404
- dct = {'lbl':lbl, 'dashboard':dashboard,
- 'item_name':item_name.replace('-', '_'),
+ dct = {'lbl': lbl, 'dashboard': dashboard,
+ 'item_name': item_name.replace('-', '_'),
'VALUE_QUOTE': '' if slicing == "year" else "'",
- 'form':form, 'slicing':slicing}
+ 'form': form, 'slicing': slicing}
n = datetime.datetime.now()
dct['unique_id'] = dct['item_name'] + "_" + \
- '%d_%d_%d' % (n.minute, n.second, n.microsecond)
+ '%d_%d_%d' % (n.minute, n.second, n.microsecond)
return render_to_response('ishtar/dashboards/dashboard_main_detail.html',
- dct, context_instance=RequestContext(request))
+ dct, context_instance=RequestContext(request))
+
def reset_wizards(request):
# dynamicaly execute each reset_wizards of each ishtar app
@@ -857,18 +893,21 @@ def reset_wizards(request):
return redirect(reverse('start'))
ITEM_PER_PAGE = 20
+
+
def merge_action(model, form, key):
def merge(request, page=1):
current_url = key + '_merge'
if not page:
page = 1
page = int(page)
- FormSet = modelformset_factory(model.merge_candidate.through,
- form=form, formset=forms.MergeFormSet ,extra=0)
+ FormSet = modelformset_factory(
+ model.merge_candidate.through, form=form,
+ formset=forms.MergeFormSet, extra=0)
q = model.merge_candidate.through.objects
- context = {'current_url':current_url,
- 'current_page':page,
- 'max_page':q.count()/ITEM_PER_PAGE}
+ context = {'current_url': current_url,
+ 'current_page': page,
+ 'max_page': q.count()/ITEM_PER_PAGE}
if page < context["max_page"]:
context['next_page'] = page + 1
if page > 1:
@@ -885,25 +924,32 @@ def merge_action(model, form, key):
context['formset'] = FormSet(request.POST, queryset=queryset)
if context['formset'].is_valid():
context['formset'].merge()
- return redirect(reverse(current_url, kwargs={'page':page}))
+ return redirect(reverse(current_url, kwargs={'page': page}))
else:
context['formset'] = FormSet(queryset=queryset)
- return render_to_response('ishtar/merge_'+key+'.html', context,
- context_instance=RequestContext(request))
+ return render_to_response(
+ 'ishtar/merge_'+key+'.html', context,
+ context_instance=RequestContext(request))
return merge
person_merge = merge_action(models.Person, forms.MergePersonForm, 'person')
-organization_merge = merge_action(models.Organization, forms.MergeOrganizationForm,
- 'organization')
+organization_merge = merge_action(
+ models.Organization,
+ forms.MergeOrganizationForm,
+ 'organization'
+)
+
class IshtarMixin(object):
page_name = u""
+
def get_context_data(self, **kwargs):
context = super(IshtarMixin, self).get_context_data(**kwargs)
context['page_name'] = self.page_name
return context
+
class LoginRequiredMixin(object):
@method_decorator(login_required)
def dispatch(self, request, *args, **kwargs):
@@ -915,12 +961,14 @@ class LoginRequiredMixin(object):
return super(LoginRequiredMixin, self).dispatch(request, *args,
**kwargs)
+
class AdminLoginRequiredMixin(LoginRequiredMixin):
def dispatch(self, request, *args, **kwargs):
if not request.user.is_staff:
return redirect(reverse('start'))
- return super(AdminLoginRequiredMixin, self).dispatch(request, *args,
- **kwargs)
+ return super(AdminLoginRequiredMixin, self).dispatch(
+ request, *args, **kwargs)
+
class GlobalVarEdit(IshtarMixin, AdminLoginRequiredMixin, ModelFormSetView):
template_name = 'ishtar/formset.html'
@@ -930,6 +978,7 @@ class GlobalVarEdit(IshtarMixin, AdminLoginRequiredMixin, ModelFormSetView):
page_name = _(u"Global variables")
fields = ['slug', 'value', 'description']
+
class NewImportView(IshtarMixin, LoginRequiredMixin, CreateView):
template_name = 'ishtar/form.html'
model = models.Import
@@ -944,6 +993,7 @@ class NewImportView(IshtarMixin, LoginRequiredMixin, CreateView):
self.object = form.save(user=user)
return HttpResponseRedirect(self.get_success_url())
+
class ImportListView(IshtarMixin, LoginRequiredMixin, ListView):
template_name = 'ishtar/import_list.html'
model = models.Import
@@ -952,8 +1002,8 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView):
def get_queryset(self):
user = models.IshtarUser.objects.get(pk=self.request.user.pk)
- return self.model.objects.filter(user=user).exclude(state='AC'
- ).order_by('-creation_date')
+ return self.model.objects.filter(user=user).exclude(
+ state='AC').order_by('-creation_date')
def post(self, request, *args, **kwargs):
for field in request.POST:
@@ -972,7 +1022,7 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView):
action = request.POST[field]
if action == 'D':
return HttpResponseRedirect(reverse('import_delete',
- kwargs={'pk':imprt.pk}))
+ kwargs={'pk': imprt.pk}))
elif action == 'A':
imprt.initialize()
elif action == 'I':
@@ -981,12 +1031,15 @@ class ImportListView(IshtarMixin, LoginRequiredMixin, ListView):
imprt.archive()
return HttpResponseRedirect(reverse(self.current_url))
+
class ImportOldListView(ImportListView):
current_url = 'old_imports'
+
def get_queryset(self):
user = models.IshtarUser.objects.get(pk=self.request.user.pk)
- return self.model.objects.filter(user=user, state='AC'
- ).order_by('-creation_date')
+ return self.model.objects.filter(
+ user=user, state='AC').order_by('-creation_date')
+
class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView):
template_name = 'ishtar/formset.html'
@@ -996,12 +1049,13 @@ class ImportLinkView(IshtarMixin, LoginRequiredMixin, ModelFormSetView):
form_class = forms.TargetKeyForm
def get_queryset(self):
- return self.model.objects.filter(is_set=False,
- associated_import=self.kwargs['pk'])
+ return self.model.objects.filter(
+ is_set=False, associated_import=self.kwargs['pk'])
def get_success_url(self):
return reverse('current_imports')
+
class ImportDeleteView(IshtarMixin, LoginRequiredMixin, DeleteView):
template_name = 'ishtar/import_delete.html'
model = models.Import
@@ -1010,6 +1064,7 @@ class ImportDeleteView(IshtarMixin, LoginRequiredMixin, DeleteView):
def get_success_url(self):
return reverse('current_imports')
+
class PersonCreate(LoginRequiredMixin, CreateView):
model = models.Person
form_class = forms.BasePersonForm
@@ -1018,6 +1073,7 @@ class PersonCreate(LoginRequiredMixin, CreateView):
def get_success_url(self):
return reverse('person_edit', args=[self.object.pk])
+
class PersonEdit(LoginRequiredMixin, UpdateView):
model = models.Person
form_class = forms.BasePersonForm
@@ -1026,6 +1082,7 @@ class PersonEdit(LoginRequiredMixin, UpdateView):
def get_success_url(self):
return reverse('person_edit', args=[self.object.pk])
+
class OrganizationCreate(LoginRequiredMixin, CreateView):
model = models.Organization
form_class = forms.BaseOrganizationForm
@@ -1038,6 +1095,7 @@ class OrganizationCreate(LoginRequiredMixin, CreateView):
kwargs.update({'prefix': self.form_class.form_prefix})
return kwargs
+
class OrganizationEdit(LoginRequiredMixin, UpdateView):
model = models.Organization
form_class = forms.BaseOrganizationForm
@@ -1049,6 +1107,7 @@ class OrganizationEdit(LoginRequiredMixin, UpdateView):
kwargs.update({'prefix': self.form_class.form_prefix})
return kwargs
+
class OrganizationPersonCreate(LoginRequiredMixin, CreateView):
model = models.Person
form_class = forms.BaseOrganizationPersonForm
@@ -1064,6 +1123,7 @@ class OrganizationPersonCreate(LoginRequiredMixin, CreateView):
def get_success_url(self):
return reverse('organization_person_edit', args=[self.object.pk])
+
class OrganizationPersonEdit(LoginRequiredMixin, UpdateView):
model = models.Person
form_class = forms.BaseOrganizationPersonForm
@@ -1072,7 +1132,7 @@ class OrganizationPersonEdit(LoginRequiredMixin, UpdateView):
def get_context_data(self, *args, **kwargs):
data = super(OrganizationPersonEdit, self).get_context_data(*args,
- **kwargs)
+ **kwargs)
data['relative_label'] = self.relative_label
return data
diff --git a/ishtar_common/widgets.py b/ishtar_common/widgets.py
index ba7e61e46..efafa38e2 100644
--- a/ishtar_common/widgets.py
+++ b/ishtar_common/widgets.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# Copyright (C) 2010-2014 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
+# Copyright (C) 2010-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet>
# Copyright (C) 2007 skam <massimo dot scamarcia at gmail.com>
# (http://djangosnippets.org/snippets/233/)
@@ -21,7 +21,7 @@
from django import forms
from django.conf import settings
-from django.core.urlresolvers import resolve, reverse
+from django.core.urlresolvers import reverse
from django.db.models import fields
from django.forms import ClearableFileInput
from django.forms.widgets import flatatt
@@ -44,7 +44,7 @@ class Select2Multiple(forms.SelectMultiple):
css = {
'all': ('select2/css/select2.css',)
}
- js = ('select2/js/select2.min.js',
+ js = ('select2/js/select2.min.js',
'select2/js/init.js')
def render(self, name, value, attrs=None, choices=()):
@@ -54,7 +54,8 @@ class Select2Multiple(forms.SelectMultiple):
attrs = {}
attrs['class'] = klass
return super(Select2Multiple, self).render(name, value, attrs,
- choices)
+ choices)
+
class MultipleAutocompleteField(forms.MultipleChoiceField):
def __init__(self, *args, **kwargs):
@@ -65,10 +66,10 @@ class MultipleAutocompleteField(forms.MultipleChoiceField):
kwargs['choices'] = []
new = kwargs.pop('new') if 'new' in kwargs else None
if 'widget' not in kwargs and self.model:
- kwargs['widget'] = JQueryAutoComplete(reverse_lazy(
- 'autocomplete-'+self.model.__name__.lower()),
- associated_model=self.model, new=new,
- multiple=True)
+ kwargs['widget'] = JQueryAutoComplete(
+ reverse_lazy('autocomplete-'+self.model.__name__.lower()),
+ associated_model=self.model, new=new,
+ multiple=True)
super(MultipleAutocompleteField, self).__init__(*args, **kwargs)
def get_choices(self):
@@ -89,17 +90,18 @@ class MultipleAutocompleteField(forms.MultipleChoiceField):
val = value
value = []
for v in val:
- v = unicode(v).strip('[').strip(']'
- ).strip('u').strip("'").strip('"')
- value += [int(v.strip())
- for v in list(set(v.split(',')))
- if v.strip()]
+ v = unicode(v).strip('[').strip(']')\
+ .strip('u').strip("'").strip('"')
+ value += [int(va.strip())
+ for va in list(set(v.split(',')))
+ if va.strip()]
except (TypeError, ValueError):
value = []
else:
value = []
return super(MultipleAutocompleteField, self).clean(value)
+
class DeleteWidget(forms.CheckboxInput):
def render(self, name, value, attrs=None):
final_attrs = flatatt(self.build_attrs(attrs, name=name,
@@ -109,28 +111,31 @@ class DeleteWidget(forms.CheckboxInput):
output.append('</td></tr>')
return mark_safe('\n'.join(output))
+
class ImageFileInput(ClearableFileInput):
template_with_initial = u'<span class="prettyPhoto">%(initial)s</span>'\
- u' %(clear_template)s<br />%(input_text)s: %(input)s'
+ u' %(clear_template)s<br />%(input_text)s: %(input)s'
+
class SquareMeterWidget(forms.TextInput):
def render(self, name, value, attrs=None):
if not value:
value = u""
final_attrs = flatatt(self.build_attrs(attrs, name=name, value=value))
- dct = {'final_attrs':final_attrs,
- 'unit':settings.SURFACE_UNIT_LABEL,
- 'id':attrs['id'],
- "safe_id":attrs['id'].replace('-', '_')}
+ dct = {'final_attrs': final_attrs,
+ 'unit': settings.SURFACE_UNIT_LABEL,
+ 'id': attrs['id'],
+ "safe_id": attrs['id'].replace('-', '_')}
t = loader.get_template('blocks/SquareMeterWidget.html')
rendered = t.render(Context(dct))
return mark_safe(rendered)
AreaWidget = forms.TextInput
+
if settings.SURFACE_UNIT == 'square-metre':
- #global AreaWidget
AreaWidget = SquareMeterWidget
+
class JQueryDate(forms.TextInput):
def __init__(self, *args, **kwargs):
super(JQueryDate, self).__init__(*args, **kwargs)
@@ -166,12 +171,14 @@ class JQueryDate(forms.TextInput):
}
$(window).load(load_jquerydate_%(var_name)s);
//--></script>
-""" % {"name":name, "var_name":var_name, "country":settings.COUNTRY}
+""" % {"name": name, "var_name": var_name, "country": settings.COUNTRY}
return rendered
+
class JQueryAutoComplete(forms.TextInput):
def __init__(self, source, associated_model=None, options={}, attrs={},
- new=False, multiple=False, limit={}):
+ new=False, url_new='', multiple=False, limit={},
+ dynamic_limit=[]):
"""
Source can be a list containing the autocomplete values or a
string containing the url used for the request.
@@ -184,8 +191,10 @@ class JQueryAutoComplete(forms.TextInput):
self.options = JSONEncoder().encode(options)
self.attrs.update(attrs)
self.new = new
+ self.url_new = url_new
self.multiple = multiple
self.limit = limit
+ self.dynamic_limit = dynamic_limit
def value_from_datadict(self, data, files, name):
if self.multiple:
@@ -203,8 +212,14 @@ class JQueryAutoComplete(forms.TextInput):
source = "'" + unicode(self.source) + "'"
except:
raise ValueError('source type is not valid')
- dct = {'source':mark_safe(source),
- 'field_id':field_id,}
+ dynamic_limit = [
+ 'id_' + lim.replace('_', '') + '-' +
+ '-'.join(field_id.split('-')[1:-1]) + '-' + lim
+ for lim in self.dynamic_limit
+ ]
+ dct = {'source': mark_safe(source),
+ 'field_id': field_id,
+ 'dynamic_limit': dynamic_limit}
if self.options:
dct['options'] = mark_safe('%s' % self.options)
@@ -253,7 +268,7 @@ class JQueryAutoComplete(forms.TextInput):
if hiddens and selects:
attrs_hidden['value'] = hiddens[0]
attrs_select['value'] = selects[0]
- if not self.attrs.has_key('id'):
+ if 'id' not in self.attrs:
attrs_hidden['id'] = 'id_%s' % name
attrs_select['id'] = 'id_select_%s' % name
if 'class' not in attrs_select:
@@ -264,11 +279,14 @@ class JQueryAutoComplete(forms.TextInput):
limits = []
for k in self.limit:
limits.append(k + "__" + "-".join(
- [unicode(v) for v in self.limit[k]]))
+ [unicode(v) for v in self.limit[k]]))
args = [attrs_select['id']]
if limits:
args.append(';'.join(limits))
- url_new = reverse('new-' + model_name, args=args)
+ url_new = 'new-' + model_name
+ if self.url_new:
+ url_new = self.url_new
+ url_new = reverse(url_new, args=args)
new = u' <a href="#" class="add-button" '\
u'onclick="open_window(\'%s\');">+</a>' % url_new
html = u'''<input%(attrs_select)s/>%(new)s\
@@ -276,13 +294,14 @@ class JQueryAutoComplete(forms.TextInput):
<script type="text/javascript"><!--//
$(function() {%(js)s});//--></script>
''' % {
- 'attrs_select' : flatatt(attrs_select),
- 'attrs_hidden' : flatatt(attrs_hidden),
- 'js' : self.render_js(name),
- 'new':new
+ 'attrs_select': flatatt(attrs_select),
+ 'attrs_hidden': flatatt(attrs_hidden),
+ 'js': self.render_js(name),
+ 'new': new
}
return html
+
class JQueryTown(forms.TextInput):
"""
Town fields whith state and department pre-selections
@@ -305,7 +324,7 @@ class JQueryTown(forms.TextInput):
if isinstance(source, list):
encoded_src = JSONEncoder().encode(source)
elif isinstance(source, str) \
- or isinstance(source, unicode):
+ or isinstance(source, unicode):
src = escape(source)
if not src.endswith('/'):
src += "/"
@@ -357,31 +376,32 @@ class JQueryTown(forms.TextInput):
if hiddens and selects:
attrs_hidden['value'] = hiddens[0]
attrs_select['value'] = selects[0]
- if not self.attrs.has_key('id'):
+ if 'id' not in self.attrs:
attrs_hidden['id'] = 'id_%s' % name
attrs_select['id'] = 'id_select_%s' % name
if 'class' not in attrs_select:
attrs_select['class'] = 'autocomplete'
source = self.encode_source(self.source)
- dct = {'source':mark_safe(source),
- 'selected':selected,
- 'safe_field_id':slugify(name).replace('-', '_'),
- 'field_id':name}
+ dct = {'source': mark_safe(source),
+ 'selected': selected,
+ 'safe_field_id': slugify(name).replace('-', '_'),
+ 'field_id': name}
if self.options:
dct['options'] = mark_safe('%s' % self.options)
- dct.update({'attrs_select':mark_safe(flatatt(attrs_select)),
- 'attrs_hidden':mark_safe(flatatt(attrs_hidden)),
- 'name':name,
- 'states':models.State.objects.all().order_by('label'),
- 'selected_department':selected_department,
- 'selected_state':selected_state
- })
- html = loader.get_template('blocks/JQueryAdvancedTown.html').render(
- Context(dct))
+ dct.update({'attrs_select': mark_safe(flatatt(attrs_select)),
+ 'attrs_hidden': mark_safe(flatatt(attrs_hidden)),
+ 'name': name,
+ 'states': models.State.objects.all().order_by('label'),
+ 'selected_department': selected_department,
+ 'selected_state': selected_state}
+ )
+ html = loader.get_template('blocks/JQueryAdvancedTown.html')\
+ .render(Context(dct))
return html
+
class JQueryPersonOrganization(forms.TextInput):
"""
Complex widget which manage:
@@ -392,7 +412,7 @@ class JQueryPersonOrganization(forms.TextInput):
def __init__(self, source, edit_source, model, options={},
attrs={}, new=False, limit={},
- html_template = 'blocks/PersonOrganization.html',
+ html_template='blocks/PersonOrganization.html',
js_template='blocks/JQueryPersonOrganization.js'):
self.options = None
self.attrs = {}
@@ -413,7 +433,7 @@ class JQueryPersonOrganization(forms.TextInput):
if isinstance(source, list):
encoded_src = JSONEncoder().encode(source)
elif isinstance(source, str) \
- or isinstance(source, unicode):
+ or isinstance(source, unicode):
encoded_src = "'%s'" % escape(source)
else:
try:
@@ -425,11 +445,11 @@ class JQueryPersonOrganization(forms.TextInput):
def render_js(self, field_id, selected=''):
source = self.encode_source(self.source)
edit_source = self.encode_source(self.edit_source)
- dct = {'source':mark_safe(source),
- 'edit_source':mark_safe(edit_source),
- 'selected':selected,
- 'safe_field_id':slugify(field_id).replace('-', '_'),
- 'field_id':field_id}
+ dct = {'source': mark_safe(source),
+ 'edit_source': mark_safe(edit_source),
+ 'selected': selected,
+ 'safe_field_id': slugify(field_id).replace('-', '_'),
+ 'field_id': field_id}
if self.options:
dct['options'] = mark_safe('%s' % self.options)
js = loader.get_template(self.js_template).render(Context(dct))
@@ -467,33 +487,33 @@ class JQueryPersonOrganization(forms.TextInput):
if hiddens and selects:
attrs_hidden['value'] = hiddens[0]
attrs_select['value'] = selects[0]
- if not self.attrs.has_key('id'):
+ if 'id' not in self.attrs:
attrs_hidden['id'] = 'id_%s' % name
attrs_select['id'] = 'id_select_%s' % name
if 'class' not in attrs_select:
attrs_select['class'] = 'autocomplete'
new = ''
- dct = {'attrs_select':mark_safe(flatatt(attrs_select)),
- 'attrs_hidden':mark_safe(flatatt(attrs_hidden)),
- 'name':name,
- 'js':self.render_js(name, selected),
- 'new':mark_safe(new)}
+ dct = {'attrs_select': mark_safe(flatatt(attrs_select)),
+ 'attrs_hidden': mark_safe(flatatt(attrs_hidden)),
+ 'name': name,
+ 'js': self.render_js(name, selected),
+ 'new': mark_safe(new)}
html = loader.get_template(self.html_template).render(Context(dct))
return html
+
class JQueryJqGrid(forms.RadioSelect):
COL_TPL = "{name:'%(idx)s', index:'%(idx)s', sortable:true}"
+
class Media:
js = ['%s/js/i18n/grid.locale-%s.js' % (settings.STATIC_URL,
settings.COUNTRY),
- '%s/js/jquery.jqGrid.min.js' % settings.STATIC_URL,
- ]
- css = {'all':['%s/media/ui.jqgrid.css' % settings.STATIC_URL,
- ]}
+ '%s/js/jquery.jqGrid.min.js' % settings.STATIC_URL]
+ css = {'all': ['%s/media/ui.jqgrid.css' % settings.STATIC_URL]}
def __init__(self, source, form, associated_model, attrs={},
- table_cols='TABLE_COLS', multiple=False, multiple_cols=[2], new=False,
- new_message="", source_full=None):
+ table_cols='TABLE_COLS', multiple=False, multiple_cols=[2],
+ new=False, new_message="", source_full=None):
self.source = source
self.form = form
self.attrs = attrs
@@ -507,7 +527,7 @@ class JQueryJqGrid(forms.RadioSelect):
def render(self, name, value=None, attrs=None):
t = loader.get_template('blocks/form_snippet.html')
form = self.form()
- rendered = t.render(Context({'form':form}))
+ rendered = t.render(Context({'form': form}))
dct = {}
if self.new:
model_name = self.associated_model._meta.object_name.lower()
@@ -516,7 +536,6 @@ class JQueryJqGrid(forms.RadioSelect):
extra_cols = []
col_names, col_idx = [], []
for k in form.get_input_ids():
- #field = form.fields[k]
col_idx.append(u'"%s"' % k)
for field_name in getattr(self.associated_model, self.table_cols):
field = self.associated_model
@@ -536,7 +555,7 @@ class JQueryJqGrid(forms.RadioSelect):
else:
continue
col_names.append(u'"%s"' % field_verbose_name)
- extra_cols.append(self.COL_TPL % {'idx':field_name})
+ extra_cols.append(self.COL_TPL % {'idx': field_name})
col_names = col_names and ", ".join(col_names) or ""
col_idx = col_idx and ", ".join(col_idx) or ""
extra_cols = extra_cols and ", ".join(extra_cols) or ""
@@ -544,19 +563,18 @@ class JQueryJqGrid(forms.RadioSelect):
dct['source'] = unicode(self.source)
if unicode(self.source_full) and unicode(self.source_full) != 'None':
dct['source_full'] = unicode(self.source_full)
- dct.update({'name':name,
- 'col_names':col_names,
- 'extra_cols':extra_cols,
- 'source':unicode(self.source),
- 'col_idx':col_idx,
- 'no_result':unicode(_("No results")),
- 'loading':unicode(_("Loading...")),
- 'remove':unicode(_(u"Remove")),
- 'sname':name.replace('-', ''),
- 'multiple':self.multiple,
- 'multi_cols': ",".join((u'"%d"' % col \
- for col in self.multiple_cols))
- })
+ dct.update({'name': name,
+ 'col_names': col_names,
+ 'extra_cols': extra_cols,
+ 'source': unicode(self.source),
+ 'col_idx': col_idx,
+ 'no_result': unicode(_("No results")),
+ 'loading': unicode(_("Loading...")),
+ 'remove': unicode(_(u"Remove")),
+ 'sname': name.replace('-', ''),
+ 'multiple': self.multiple,
+ 'multi_cols': ",".join((u'"%d"' % col
+ for col in self.multiple_cols))})
t = loader.get_template('blocks/JQueryJqGrid.html')
rendered += t.render(Context(dct))
return mark_safe(rendered)
diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py
index af236504c..7da654b80 100644
--- a/ishtar_common/wizards.py
+++ b/ishtar_common/wizards.py
@@ -23,13 +23,15 @@ from django.conf import settings
from django.contrib.formtools.wizard.storage import get_storage
from django.contrib.formtools.wizard.views import NamedUrlWizardView, \
normalize_name
+from django.contrib.sites.models import Site
from django.core.exceptions import ObjectDoesNotExist
from django.core.files.images import ImageFile
+from django.core.mail import send_mail
from django.db.models.fields.files import FileField
from django.db.models.fields.related import ManyToManyField
from django.forms import ValidationError
from django.shortcuts import render_to_response
-from django.template import RequestContext
+from django.template import Context, RequestContext, loader
from django.utils.datastructures import MultiValueDict as BaseMultiValueDict
from django.utils.translation import ugettext_lazy as _
import models
@@ -216,12 +218,13 @@ class Wizard(NamedUrlWizardView):
if form_datas:
form_datas.append(("", "", "spacer"))
items = hasattr(base_form, 'fields') and \
- base_form.fields.keyOrder or cleaned_data.keys()
+ base_form.fields.keyOrder or cleaned_data.keys()
for key in items:
lbl = None
if key.startswith('hidden_'):
continue
- if hasattr(base_form, 'fields') and key in base_form.fields:
+ if hasattr(base_form, 'fields') \
+ and key in base_form.fields:
lbl = base_form.fields[key].label
if hasattr(base_form, 'associated_labels') \
and key in base_form.associated_labels:
@@ -229,22 +232,22 @@ class Wizard(NamedUrlWizardView):
if not lbl:
continue
value = cleaned_data[key]
- if not value and value != False:
+ if value is None or value == '':
continue
if key in self.translated_keys:
value = _(value)
if type(value) == bool:
- if value == True:
+ if value:
value = _(u"Yes")
- elif value == False:
+ else:
value = _(u"No")
elif key in associated_models:
values = []
if type(value) in (tuple, list):
values = value
elif "," in unicode(value):
- values = unicode(value
- ).strip('[').strip(']').split(",")
+ values = unicode(
+ value).strip('[').strip(']').split(",")
else:
values = [value]
rendered_values = []
@@ -274,7 +277,7 @@ class Wizard(NamedUrlWizardView):
return self.render(form)
base_form = hasattr(form, 'forms') and form.forms[0] or form
associated_models = hasattr(base_form, 'associated_models') and \
- base_form.associated_models or {}
+ base_form.associated_models or {}
if hasattr(form, 'forms'):
multi = False
if form.forms:
@@ -289,7 +292,8 @@ class Wizard(NamedUrlWizardView):
multi = len(fields) > 1
if multi:
assert hasattr(frm, 'base_model'), \
- u"Must define a base_model for " + unicode(frm.__class__)
+ u"Must define a base_model for " + \
+ unicode(frm.__class__)
for frm in form.forms:
if not frm.is_valid():
continue
@@ -300,10 +304,11 @@ class Wizard(NamedUrlWizardView):
frm.cleaned_data.pop('DELETE')
for key in frm.cleaned_data:
value = frm.cleaned_data[key]
- if not value and value != False:
+ if value is None or value == '':
continue
if key in associated_models:
- value = associated_models[key].objects.get(pk=value)
+ value = associated_models[key].objects.get(
+ pk=value)
if multi:
vals[key] = value
else:
@@ -319,10 +324,10 @@ class Wizard(NamedUrlWizardView):
if value:
model = associated_models[key]
if isinstance(value, unicode) \
- or isinstance(value, str) and "," in value:
+ or isinstance(value, str) and "," in value:
value = value.split(",")
if isinstance(value, list) \
- or isinstance(value, tuple):
+ or isinstance(value, tuple):
value = [model.objects.get(pk=val)
for val in value if val]
if len(value) == 1:
@@ -346,11 +351,11 @@ class Wizard(NamedUrlWizardView):
return_object)
def get_saved_model(self):
- """Permit a distinguo when saved model is not the base selected model"""
+ "Permit a distinguo when saved model is not the base selected model"
return self.model
def get_current_saved_object(self):
- """Permit a distinguo when saved model is not the base selected model"""
+ "Permit a distinguo when saved model is not the base selected model"
return self.get_current_object()
def save_model(self, dct, m2m, whole_associated_models, form_list,
@@ -363,7 +368,8 @@ class Wizard(NamedUrlWizardView):
if '__' not in k:
continue
vals = k.split('__')
- assert len(vals) == 2, "Only one level of dependant item is managed"
+ assert len(vals) == 2, \
+ "Only one level of dependant item is managed"
dependant_item, key = vals
if dependant_item not in other_objs:
other_objs[dependant_item] = {}
@@ -388,7 +394,7 @@ class Wizard(NamedUrlWizardView):
setattr(obj, k, dct[k])
try:
obj.full_clean()
- except ValidationError, msg:
+ except ValidationError:
return self.render(form_list[-1])
for dependant_item in other_objs:
c_item = getattr(obj, dependant_item)
@@ -429,7 +435,7 @@ class Wizard(NamedUrlWizardView):
obj = self.get_saved_model()(**dct)
try:
obj.full_clean()
- except ValidationError, msg:
+ except ValidationError:
return self.render(form_list[-1])
obj.save()
for k in adds:
@@ -463,13 +469,13 @@ class Wizard(NamedUrlWizardView):
# necessary to manage interaction between models like
# material_index management for baseitems
obj.save()
- dct = {'item':obj}
+ dct = {'item': obj}
# force evaluation of lazy urls
wizard_done_window = unicode(self.wizard_done_window)
if wizard_done_window:
dct['wizard_done_window'] = wizard_done_window
res = render_to_response(self.wizard_done_template, dct,
- context_instance=RequestContext(self.request))
+ context_instance=RequestContext(self.request))
return return_object and (obj, res) or res
def get_deleted(self, keys):
@@ -494,8 +500,6 @@ class Wizard(NamedUrlWizardView):
def get_form(self, step=None, data=None, files=None):
"""Manage formset"""
- request = self.request
- storage = self.storage
if data:
data = data.copy()
if not step:
@@ -513,7 +517,7 @@ class Wizard(NamedUrlWizardView):
if to_delete:
# reorganize
for idx, number in enumerate(sorted(not_to_delete,
- key=lambda x:int(x))):
+ key=lambda x: int(x))):
idx = unicode(idx)
if idx == number:
continue
@@ -527,8 +531,8 @@ class Wizard(NamedUrlWizardView):
frm = form.form
if callable(frm):
frm = frm()
- required_fields = [k for k in frm.fields
- if frm.fields[k].required]
+ required_fields = [ki for ki in frm.fields
+ if frm.fields[ki].required]
base_key = None
if required_fields:
base_key = required_fields[-1]
@@ -538,8 +542,8 @@ class Wizard(NamedUrlWizardView):
total_field = 0
if base_key:
total_field = len([key for key in data.keys()
- if base_key in key.split('-')
- and data[key]])
+ if base_key in key.split('-')
+ and data[key]])
if init and not to_delete and (
not hasattr(self, 'form_initialized') or
not self.form_initialized):
@@ -548,7 +552,8 @@ class Wizard(NamedUrlWizardView):
data[step + u'-TOTAL_FORMS'] = unicode(total_field + 1)
# TODO:remove form_initialized?
# update initialization
- #if request.POST and init and hasattr(self, 'form_initialized') \
+ # if request.POST and init and hasattr(self,
+ # 'form_initialized') \
# and self.form_initialized:
# for k in init[0]:
# data[step + '-' + unicode(total_field) + '-' + k] = \
@@ -560,15 +565,15 @@ class Wizard(NamedUrlWizardView):
if hasattr(form, 'fields') and form.fields.keys():
frm = form
elif hasattr(form, 'extra_form') and hasattr(form.extra_form, 'fields')\
- and form.extra_form.fields.keys():
+ and form.extra_form.fields.keys():
frm = form.extra_form
elif hasattr(form, 'forms') and form.forms \
- and form.forms[0].fields.keys():
+ and form.forms[0].fields.keys():
frm = form.forms[0]
if frm:
first_field = frm.fields[frm.fields.keyOrder[0]]
attrs = first_field.widget.attrs
- attrs.update({'autofocus':"autofocus"})
+ attrs.update({'autofocus': "autofocus"})
first_field.widget.attrs = attrs
return form
@@ -584,10 +589,11 @@ class Wizard(NamedUrlWizardView):
or [key for key in request.POST.keys()
if key.endswith('DELETE') and request.POST[key]]:
return self.render(form)
- elif request.POST.has_key('validate_and_end') \
- and request.POST['validate_and_end']:
+ elif 'validate_and_end' in request.POST \
+ and request.POST['validate_and_end']:
last_step = self.steps.last
- new_form = self.get_form(last_step,
+ new_form = self.get_form(
+ last_step,
data=self.storage.get_step_data(last_step),
files=self.storage.get_step_files(last_step))
self.storage.current_step = last_step
@@ -668,9 +674,8 @@ class Wizard(NamedUrlWizardView):
vals = []
for k in request.session[storage.prefix]['step_data'][form_key]:
if k.startswith(form_key) and k.endswith(key) and \
- request.session[storage.prefix]['step_data'][form_key][k]:
- val = request.session[storage.prefix]['step_data']\
- [form_key][k]
+ request.session[storage.prefix]['step_data'][form_key][k]:
+ val = request.session[storage.prefix]['step_data'][form_key][k]
if type(val) in (list, tuple):
val = val[0]
vals.append(val)
@@ -694,13 +699,13 @@ class Wizard(NamedUrlWizardView):
request = self.request
if step.startswith('selec-') and step in self.form_list \
and 'pk' in self.form_list[step].associated_models:
- model_name = self.form_list[step].associated_models['pk'
- ].__name__.lower()
+ model_name = self.form_list[step]\
+ .associated_models['pk'].__name__.lower()
if step == current_step:
self.storage.reset()
val = model_name in request.session and request.session[model_name]
if val:
- return MultiValueDict({'pk':val})
+ return MultiValueDict({'pk': val})
elif current_obj:
return self.get_instanced_init(current_obj, step)
current_form = self.form_list[current_step]
@@ -709,7 +714,7 @@ class Wizard(NamedUrlWizardView):
for key in current_form.currents:
model_name = current_form.currents[key].__name__.lower()
val = model_name in request.session and \
- request.session[model_name]
+ request.session[model_name]
if val:
initial[key] = val
if initial:
@@ -729,8 +734,8 @@ class Wizard(NamedUrlWizardView):
self.request.session[obj_name] = unicode(obj.pk)
initial = MultiValueDict()
if self.request.POST or \
- (step in self.request.session[self.storage.prefix] and\
- self.request.session[self.storage.prefix]['step_data'][step]):
+ (step in self.request.session[self.storage.prefix] and
+ self.request.session[self.storage.prefix]['step_data'][step]):
return initial
if hasattr(c_form, 'base_fields'):
for base_field in c_form.base_fields.keys():
@@ -738,13 +743,13 @@ class Wizard(NamedUrlWizardView):
if hasattr(c_form, 'base_model') and \
base_field == c_form.base_model:
key = c_form.base_model + 's'
- initial.setlist(base_field, [unicode(val.pk)
- for val in getattr(obj, key).all()])
+ initial.setlist(base_field, [
+ unicode(val.pk) for val in getattr(obj, key).all()])
else:
fields = base_field.split('__')
for field in fields:
if not hasattr(value, field) or \
- getattr(value, field) == None:
+ getattr(value, field) is None:
value = obj
break
value = getattr(value, field)
@@ -762,7 +767,7 @@ class Wizard(NamedUrlWizardView):
isinstance(value, FileField) or \
isinstance(value, ImageFile):
initial[base_field] = value
- elif value != None:
+ elif value is not None:
initial[base_field] = unicode(value)
elif hasattr(c_form, 'management_form'):
initial = []
@@ -789,7 +794,7 @@ class Wizard(NamedUrlWizardView):
value = getattr(child_obj, field)
if hasattr(value, 'pk'):
value = value.pk
- if value != None:
+ if value is not None:
vals[field] = unicode(value)
if vals:
initial.append(vals)
@@ -799,8 +804,9 @@ class Wizard(NamedUrlWizardView):
class SearchWizard(NamedUrlWizardView):
model = None
label = ''
- modification = None # True when the wizard modify an item
- storage_name = 'django.contrib.formtools.wizard.storage.session.SessionStorage'
+ modification = None # True when the wizard modify an item
+ storage_name = \
+ 'django.contrib.formtools.wizard.storage.session.SessionStorage'
def get_wizard_name(self):
"""
@@ -812,7 +818,7 @@ class SearchWizard(NamedUrlWizardView):
"""As the class name can interfere when reused prefix with the url_name
"""
return self.url_name + super(SearchWizard, self).get_prefix(*args,
- **kwargs)
+ **kwargs)
def get_template_names(self):
templates = ['ishtar/wizard/search.html']
@@ -822,8 +828,8 @@ class SearchWizard(NamedUrlWizardView):
context = super(SearchWizard, self).get_context_data(form)
self.request.session['CURRENT_ACTION'] = self.get_wizard_name()
current_step = self.steps.current
- context.update({'current_step':self.form_list[current_step],
- 'wizard_label':self.label})
+ context.update({'current_step': self.form_list[current_step],
+ 'wizard_label': self.label})
return context
@@ -843,7 +849,8 @@ class DeletionWizard(Wizard):
for key in form.cleaned_data:
if key == 'pk':
model = form.associated_models['pk']
- self.current_obj = model.objects.get(pk=form.cleaned_data['pk'])
+ self.current_obj = model.objects.get(
+ pk=form.cleaned_data['pk'])
if not self.current_obj:
return datas
res = {}
@@ -873,8 +880,9 @@ class DeletionWizard(Wizard):
obj.delete()
except ObjectDoesNotExist:
pass
- return render_to_response('ishtar/wizard/wizard_delete_done.html', {},
- context_instance=RequestContext(self.request))
+ return render_to_response(
+ 'ishtar/wizard/wizard_delete_done.html', {},
+ context_instance=RequestContext(self.request))
class ClosingWizard(Wizard):
@@ -893,7 +901,7 @@ class ClosingWizard(Wizard):
if key == 'pk':
model = form.associated_models['pk']
self.current_obj = model.objects.get(
- pk=form.cleaned_data['pk'])
+ pk=form.cleaned_data['pk'])
if not self.current_obj:
return datas
res = {}
@@ -921,11 +929,13 @@ class ClosingWizard(Wizard):
obj = self.get_current_object()
for form in form_list:
if form.is_valid():
- if 'end_date' in form.cleaned_data and hasattr(obj, 'end_date'):
+ if 'end_date' in form.cleaned_data \
+ and hasattr(obj, 'end_date'):
obj.end_date = form.cleaned_data['end_date']
obj.save()
- return render_to_response('ishtar/wizard/wizard_closing_done.html', {},
- context_instance=RequestContext(self.request))
+ return render_to_response(
+ 'ishtar/wizard/wizard_closing_done.html', {},
+ context_instance=RequestContext(self.request))
class PersonWizard(Wizard):
@@ -940,7 +950,7 @@ class PersonDeletionWizard(DeletionWizard):
model = models.Person
fields = model.TABLE_COLS
wizard_templates = {
- 'final-person_deletion':'ishtar/wizard/wizard_person_deletion.html'}
+ 'final-person_deletion': 'ishtar/wizard/wizard_person_deletion.html'}
class OrganizationWizard(Wizard):
@@ -955,12 +965,13 @@ class OrganizationDeletionWizard(DeletionWizard):
model = models.Organization
fields = model.TABLE_COLS
wizard_templates = {
- 'final-organization_deletion':\
- 'ishtar/wizard/wizard_organization_deletion.html'}
+ 'final-organization_deletion':
+ 'ishtar/wizard/wizard_organization_deletion.html'}
class AccountWizard(Wizard):
model = models.Person
+
def get_formated_datas(self, forms):
datas = super(AccountWizard, self).get_formated_datas(forms)
for form in forms:
@@ -980,7 +991,7 @@ class AccountWizard(Wizard):
if not form.is_valid():
return self.render(form)
associated_models = hasattr(form, 'associated_models') and \
- form.associated_models or {}
+ form.associated_models or {}
if type(form.cleaned_data) == dict:
for key in form.cleaned_data:
if key == 'pk':
@@ -1001,10 +1012,11 @@ class AccountWizard(Wizard):
account.email = dct['email']
except ObjectDoesNotExist:
now = datetime.datetime.now()
- account = models.IshtarUser(person=person, username=dct['username'],
- email=dct['email'], first_name=person.surname,
- last_name=person.name, is_staff=False, is_active=True,
- is_superuser=False, last_login=now, date_joined=now)
+ account = models.IshtarUser(
+ person=person, username=dct['username'], email=dct['email'],
+ first_name=person.surname, last_name=person.name,
+ is_staff=False, is_active=True, is_superuser=False,
+ last_login=now, date_joined=now)
if dct['password']:
account.set_password(dct['password'])
account.save()
@@ -1014,20 +1026,21 @@ class AccountWizard(Wizard):
site = Site.objects.get_current()
app_name = site and ("Ishtar - " + site.name) \
- or "Ishtar"
- context = Context({'login':dct['username'],
- 'password':dct['password'],
- 'app_name':app_name,
- 'site': site and site.domain or ""
- })
+ or "Ishtar"
+ context = Context({
+ 'login': dct['username'],
+ 'password': dct['password'],
+ 'app_name': app_name,
+ 'site': site and site.domain or ""
+ })
t = loader.get_template('account_activation_email.txt')
msg = t.render(context)
subject = _(u"[%(app_name)s] Account creation/modification") % {
- "app_name":app_name}
+ "app_name": app_name}
send_mail(subject, msg, settings.ADMINS[0][1],
[dct['email']], fail_silently=True)
res = render_to_response('ishtar/wizard/wizard_done.html', {},
- context_instance=RequestContext(self.request))
+ context_instance=RequestContext(self.request))
return res
def get_form(self, step=None, data=None, files=None):
@@ -1045,6 +1058,7 @@ class AccountWizard(Wizard):
class SourceWizard(Wizard):
model = None
+
def get_extra_model(self, dct, form_list):
dct = super(SourceWizard, self).get_extra_model(dct, form_list)
if 'history_modifier' in dct: