diff options
-rw-r--r-- | archaeological_operations/admin.py | 43 | ||||
-rw-r--r-- | archaeological_operations/lookups.py | 41 | ||||
-rw-r--r-- | archaeological_operations/models.py | 10 | ||||
-rw-r--r-- | example_project/settings.py | 2 | ||||
-rw-r--r-- | ishtar_common/static/ajax_select/css/ajax_select.css | 49 | ||||
-rw-r--r-- | ishtar_common/templates/admin/base_site.html | 10 |
6 files changed, 136 insertions, 19 deletions
diff --git a/archaeological_operations/admin.py b/archaeological_operations/admin.py index 3cfd91d5e..f1deac188 100644 --- a/archaeological_operations/admin.py +++ b/archaeological_operations/admin.py @@ -75,6 +75,13 @@ class ArchaeologicalSiteAdmin(HistorizedObjectAdmin): admin_site.register(models.ArchaeologicalSite, ArchaeologicalSiteAdmin) +class ArchaeologicalSiteInline(admin.TabularInline): + model = models.Operation.archaeological_sites.through + form = make_ajax_form( + model, {'archaeologicalsite': 'archaeological_site'}) + extra = 1 + + class AdminOperationForm(forms.ModelForm): class Meta: model = models.Operation @@ -107,6 +114,7 @@ class OperationAdmin(HistorizedObjectAdmin): readonly_fields = HistorizedObjectAdmin.readonly_fields + [ 'imports', 'cached_label'] form = AdminOperationForm + inlines = [ArchaeologicalSiteInline] admin_site.register(models.Operation, OperationAdmin) @@ -126,8 +134,18 @@ admin_site.register(models.OperationSource, OperationSourceAdmin) class ParcelAdmin(HistorizedObjectAdmin): list_display = ['section', 'parcel_number', 'operation', 'associated_file'] - search_fields = ('operation__name',) + search_fields = ('operation__cached_label', + 'associated_file__cached_label', + 'year', 'section', 'parcel_number') model = models.Parcel + form = make_ajax_form( + model, {'associated_file': 'file', + 'operation': 'operation', + 'town': 'town'} + ) + readonly_fields = HistorizedObjectAdmin.readonly_fields + [ + 'imports', 'history_date' + ] admin_site.register(models.Parcel, ParcelAdmin) @@ -165,10 +183,25 @@ class ReportStateAdmin(GeneralTypeAdmin): admin_site.register(models.ReportState, ReportStateAdmin) +class ParcelOwnerAdmin(HistorizedObjectAdmin): + list_display = ['parcel', 'operation', 'associated_file', + 'owner'] + search_fields = ('parcel__operation__cached_label', + 'parcel__associated_file__cached_label', + 'owner__name', 'owner__surname', 'parcel__section', + 'parcel__parcel_number') + model = models.ParcelOwner + form = make_ajax_form( + model, {'owner': 'person', + 'parcel': 'parcel'} + ) + readonly_fields = HistorizedObjectAdmin.readonly_fields + [ + 'imports', 'history_date' + ] + +admin_site.register(models.ParcelOwner, ParcelOwnerAdmin) + + general_models = [models.RemainType] for model in general_models: admin_site.register(model, GeneralTypeAdmin) - -basic_models = [models.ParcelOwner] -for model in basic_models: - admin_site.register(model) diff --git a/archaeological_operations/lookups.py b/archaeological_operations/lookups.py index 690b3c566..83cf6fa3a 100644 --- a/archaeological_operations/lookups.py +++ b/archaeological_operations/lookups.py @@ -1,7 +1,11 @@ from ajax_select import register, LookupChannel from django.db.models import Q -from archaeological_operations.models import Operation, ArchaeologicalSite +from django.utils.encoding import force_text +from django.utils.html import escape + +from archaeological_operations.models import Operation, ArchaeologicalSite, \ + Parcel @register('operation') @@ -33,7 +37,40 @@ class ArchaeologicalSiteLookup(LookupChannel): Q(name__icontains=term) ) query &= subquery - return self.model.objects.filter(query).order_by('cached_label')[:20] + return self.model.objects.filter(query).order_by('reference', + 'name')[:20] def format_item_display(self, item): return u"<span class='ajax-label'>%s</span>" % unicode(item) + + +@register('parcel') +class ParcelLookup(LookupChannel): + model = Parcel + + def get_query(self, q, request): + query = Q() + for term in q.strip().split(' '): + subquery = ( + Q(associated_file__cached_label__icontains=term) | + Q(operation__cached_label__icontains=term) | + Q(section__icontains=term) | + Q(parcel_number__icontains=term) | + Q(town__name__icontains=term) + ) + try: + subquery |= Q(year=int(term)) + except ValueError: + pass + query &= subquery + return self.model.objects.filter( + query).order_by('-associated_file__cached_label', + '-operation__cached_label', + 'section', + 'parcel_number')[:20] + + def format_match(self, obj): + return escape(force_text(obj.long_label())) + + def format_item_display(self, item): + return u"<span class='ajax-label'>%s</span>" % item.long_label() diff --git a/archaeological_operations/models.py b/archaeological_operations/models.py index 1249fcc05..ba947e8bb 100644 --- a/archaeological_operations/models.py +++ b/archaeological_operations/models.py @@ -1473,7 +1473,15 @@ class ParcelOwner(LightHistorizedItem): verbose_name_plural = _(u"Parcel owners") def __unicode__(self): - return self.owner + settings.JOINT + self.parcel + return "{}{}{}".format(self.owner, settings.JOINT, self.parcel) + + @property + def operation(self): + return self.parcel.operation + + @property + def associated_file(self): + return self.parcel.associated_file class OperationDashboard: diff --git a/example_project/settings.py b/example_project/settings.py index d737fa29f..6b3022089 100644 --- a/example_project/settings.py +++ b/example_project/settings.py @@ -142,7 +142,6 @@ INSTALLED_APPS = [ 'django.contrib.humanize', 'registration', # 'geodjangofla', - 'ajax_select', 'ishtar_pdl', 'ishtar_common', 'archaeological_files_pdl', @@ -151,6 +150,7 @@ INSTALLED_APPS = [ 'archaeological_context_records', 'archaeological_warehouse', 'archaeological_finds', + 'ajax_select', # 'debug_toolbar', ] diff --git a/ishtar_common/static/ajax_select/css/ajax_select.css b/ishtar_common/static/ajax_select/css/ajax_select.css new file mode 100644 index 000000000..379b5be96 --- /dev/null +++ b/ishtar_common/static/ajax_select/css/ajax_select.css @@ -0,0 +1,49 @@ +.results_on_deck .ui-icon-trash { + float: left; + cursor: pointer; +} +.results_on_deck { + padding: 0.25em 0; +} +form .aligned .results_on_deck { + padding-left: 38px; + margin-left: 7em; +} +.results_on_deck > div { + margin-bottom: 0.5em; +} +.ui-autocomplete-loading { + background: url('../images/loading-indicator.gif') no-repeat; + background-origin: content-box; + background-position: right; +} +ul.ui-autocomplete { + /* + this is the dropdown menu. + + if max-width is not set and you are using django-admin + then the dropdown is the width of your whole page body (totally wrong). + + this sets max-width at 60% which is graceful at full page or in a popup + or on a small width window. + + fixed width is harder see http://stackoverflow.com/questions/4607164/changing-width-of-jquery-ui-autocomplete-widgets-individually + */ + max-width: 60%; + margin: 0; + padding: 0; + position: absolute; +} +ul.ui-autocomplete li { + list-style-type: none; + padding: 0; +} +ul.ui-autocomplete li a { + display: block; + padding: 2px 3px; + cursor: pointer; +} + +.results_on_deck .ajax-label{ + line-height: 18px; +} diff --git a/ishtar_common/templates/admin/base_site.html b/ishtar_common/templates/admin/base_site.html deleted file mode 100644 index 3282d4f5a..000000000 --- a/ishtar_common/templates/admin/base_site.html +++ /dev/null @@ -1,10 +0,0 @@ -{% extends "admin/base.html" %} -{% load i18n %} - -{% block title %}{{ title }} | {% trans 'Ishtar administration' %}{% endblock %} - -{% block branding %} -<h1 id="site-name">{% trans 'Ishtar administration' %}</h1> -{% endblock %} - -{% block nav-global %}{% endblock %} |