diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-12-13 23:54:02 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-12-13 23:54:56 +0100 |
commit | 8f8e446022e9dd508572c92ed5244397e2225087 (patch) | |
tree | 30eacfb929844256a5beca6c5ab58eb3e36d759e | |
parent | 5836947ae64f178e87339045d80788c344924d02 (diff) | |
download | Ishtar-8f8e446022e9dd508572c92ed5244397e2225087.tar.bz2 Ishtar-8f8e446022e9dd508572c92ed5244397e2225087.zip |
Manage warehouse forms. Add warehouse division management
-rw-r--r-- | archaeological_warehouse/admin.py | 11 | ||||
-rw-r--r-- | archaeological_warehouse/forms.py | 23 | ||||
-rw-r--r-- | archaeological_warehouse/migrations/0010_auto__add_warehousedivisionlink__add_warehousedivision__chg_field_ware.py (renamed from archaeological_warehouse/migrations/0010_auto__add_warehousedivision__chg_field_warehouse_name.py) | 34 | ||||
-rw-r--r-- | archaeological_warehouse/models.py | 23 | ||||
-rw-r--r-- | archaeological_warehouse/views.py | 2 | ||||
-rw-r--r-- | ishtar_common/wizards.py | 28 |
6 files changed, 95 insertions, 26 deletions
diff --git a/archaeological_warehouse/admin.py b/archaeological_warehouse/admin.py index 1d5618805..911809d0f 100644 --- a/archaeological_warehouse/admin.py +++ b/archaeological_warehouse/admin.py @@ -33,15 +33,6 @@ class WarehouseAdmin(HistorizedObjectAdmin): admin.site.register(models.Warehouse, WarehouseAdmin) -class WarehouseDivisionAdmin(admin.ModelAdmin): - list_display = ('name', 'warehouse', 'order') - list_filter = ('warehouse',) - search_fields = ('warehouse__name',) - model = models.WarehouseDivision - -admin.site.register(models.WarehouseDivision, WarehouseDivisionAdmin) - - class ContainerTypeAdmin(admin.ModelAdmin): list_display = ('label', 'reference', 'length', 'width', 'height', 'volume') @@ -57,6 +48,6 @@ class ContainerAdmin(admin.ModelAdmin): admin.site.register(models.Container, ContainerAdmin) -general_models = [models.WarehouseType] +general_models = [models.WarehouseType, models.WarehouseDivision] for model in general_models: admin.site.register(model, GeneralTypeAdmin) diff --git a/archaeological_warehouse/forms.py b/archaeological_warehouse/forms.py index f73dac22e..2e243b092 100644 --- a/archaeological_warehouse/forms.py +++ b/archaeological_warehouse/forms.py @@ -19,6 +19,7 @@ from django import forms from django.conf import settings +from django.forms.formsets import formset_factory from django.utils.translation import ugettext_lazy as _ from ishtar_common.models import Person, valid_id @@ -39,6 +40,28 @@ def get_warehouse_field(label=_(u"Warehouse"), required=True): validators=[valid_id(models.Warehouse)]) +class SelectedDivisionForm(ManageOldType, forms.Form): + form_label = _(u"Division") + base_model = 'associated_division' + associated_models = {'division': models.WarehouseDivision, + 'associated_division': models.WarehouseDivisionLink} + division = forms.ChoiceField( + label=_(u"Division"), choices=(), required=False, + validators=[valid_id(models.WarehouseDivision)]) + order = forms.IntegerField(_(u"Order"), initial=10, required=False) + + def __init__(self, *args, **kwargs): + super(SelectedDivisionForm, self).__init__(*args, **kwargs) + self.fields['division'].choices = \ + models.WarehouseDivision.get_types( + initial=self.init_data.get('division') + ) + +SelectedDivisionFormset = formset_factory( + SelectedDivisionForm, can_delete=True) +SelectedDivisionFormset.form_label = _(u"Divisions") + + class WarehouseSelect(TableSelect): name = forms.CharField(label=_(u"Name")) warehouse_type = forms.ChoiceField(label=_(u"Warehouse type"), choices=[]) diff --git a/archaeological_warehouse/migrations/0010_auto__add_warehousedivision__chg_field_warehouse_name.py b/archaeological_warehouse/migrations/0010_auto__add_warehousedivisionlink__add_warehousedivision__chg_field_ware.py index c0844ab9d..306ebe290 100644 --- a/archaeological_warehouse/migrations/0010_auto__add_warehousedivision__chg_field_warehouse_name.py +++ b/archaeological_warehouse/migrations/0010_auto__add_warehousedivisionlink__add_warehousedivision__chg_field_ware.py @@ -8,12 +8,22 @@ from django.db import models class Migration(SchemaMigration): def forwards(self, orm): + # Adding model 'WarehouseDivisionLink' + db.create_table('archaeological_warehouse_warehousedivisionlink', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('warehouse', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_warehouse.Warehouse'])), + ('division', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['archaeological_warehouse.WarehouseDivision'])), + ('order', self.gf('django.db.models.fields.IntegerField')(default=10)), + )) + db.send_create_signal('archaeological_warehouse', ['WarehouseDivisionLink']) + # Adding model 'WarehouseDivision' db.create_table('archaeological_warehouse_warehousedivision', ( ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('name', self.gf('django.db.models.fields.CharField')(max_length=200)), - ('order', self.gf('django.db.models.fields.IntegerField')(default=1)), - ('warehouse', self.gf('django.db.models.fields.related.ForeignKey')(related_name='divisions', to=orm['archaeological_warehouse.Warehouse'])), + ('label', self.gf('django.db.models.fields.CharField')(max_length=100)), + ('txt_idx', self.gf('django.db.models.fields.CharField')(unique=True, max_length=100)), + ('comment', self.gf('django.db.models.fields.TextField')(null=True, blank=True)), + ('available', self.gf('django.db.models.fields.BooleanField')(default=True)), )) db.send_create_signal('archaeological_warehouse', ['WarehouseDivision']) @@ -22,6 +32,9 @@ class Migration(SchemaMigration): db.alter_column('archaeological_warehouse_warehouse', 'name', self.gf('django.db.models.fields.CharField')(max_length=200)) def backwards(self, orm): + # Deleting model 'WarehouseDivisionLink' + db.delete_table('archaeological_warehouse_warehousedivisionlink') + # Deleting model 'WarehouseDivision' db.delete_table('archaeological_warehouse_warehousedivision') @@ -67,6 +80,7 @@ class Migration(SchemaMigration): 'alt_town': ('django.db.models.fields.CharField', [], {'max_length': '70', 'null': 'True', 'blank': 'True'}), 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), 'country': ('django.db.models.fields.CharField', [], {'max_length': '30', 'null': 'True', 'blank': 'True'}), + 'divisions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['archaeological_warehouse.WarehouseDivision']", 'symmetrical': 'False', 'through': "orm['archaeological_warehouse.WarehouseDivisionLink']", 'blank': 'True'}), 'email': ('django.db.models.fields.EmailField', [], {'max_length': '300', 'null': 'True', 'blank': 'True'}), 'history_creator': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), 'history_modifier': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'on_delete': 'models.SET_NULL', 'to': "orm['auth.User']"}), @@ -88,10 +102,18 @@ class Migration(SchemaMigration): }, 'archaeological_warehouse.warehousedivision': { 'Meta': {'object_name': 'WarehouseDivision'}, + 'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), + 'comment': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), - 'warehouse': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'divisions'", 'to': "orm['archaeological_warehouse.Warehouse']"}) + 'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'txt_idx': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '100'}) + }, + 'archaeological_warehouse.warehousedivisionlink': { + 'Meta': {'ordering': "('warehouse', 'order')", 'object_name': 'WarehouseDivisionLink'}, + 'division': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_warehouse.WarehouseDivision']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'order': ('django.db.models.fields.IntegerField', [], {'default': '10'}), + 'warehouse': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['archaeological_warehouse.Warehouse']"}) }, 'archaeological_warehouse.warehousetype': { 'Meta': {'ordering': "('label',)", 'object_name': 'WarehouseType'}, diff --git a/archaeological_warehouse/models.py b/archaeological_warehouse/models.py index 579c448ae..7d37bd664 100644 --- a/archaeological_warehouse/models.py +++ b/archaeological_warehouse/models.py @@ -42,6 +42,10 @@ class Warehouse(Address, OwnPerms): Person, on_delete=models.SET_NULL, related_name='warehouse_in_charge', verbose_name=_(u"Person in charge"), null=True, blank=True) comment = models.TextField(_(u"Comment"), null=True, blank=True) + associated_divisions = models.ManyToManyField( + 'WarehouseDivision', verbose_name=_("Divisions"), blank=True, + through='WarehouseDivisionLink' + ) TABLE_COLS = ['name', 'warehouse_type'] @@ -60,18 +64,21 @@ class Warehouse(Address, OwnPerms): return u"%s (%s)" % (self.name, unicode(self.warehouse_type)) -class WarehouseDivision(models.Model): - name = models.CharField(_(u"Name"), max_length=200) - order = models.IntegerField(_(u"Order"), default=1) - warehouse = models.ForeignKey(Warehouse, verbose_name=_(u"Warehouse"), - related_name='divisions') - +class WarehouseDivision(GeneralType): class Meta: verbose_name = _(u"Warehouse division") verbose_name_plural = _(u"Warehouse divisions") - def __unicode__(self): - return u"%s (%s)" % (self.name, unicode(self.warehouse)) + +class WarehouseDivisionLink(models.Model): + RELATIVE_MODELS = {Warehouse: 'warehouse'} + warehouse = models.ForeignKey(Warehouse) + division = models.ForeignKey(WarehouseDivision) + order = models.IntegerField(_("Order"), default=10) + + class Meta: + ordering = ('warehouse', 'order') + unique_together = ('warehouse', 'division') class ContainerType(GeneralType): diff --git a/archaeological_warehouse/views.py b/archaeological_warehouse/views.py index 385a373e7..cfc05a036 100644 --- a/archaeological_warehouse/views.py +++ b/archaeological_warehouse/views.py @@ -91,6 +91,7 @@ warehouse_packaging_wizard = PackagingWizard.as_view([ warehouse_creation_wizard = WarehouseWizard.as_view([ ("warehouse-warehouse_creation", WarehouseForm), + ('divisions-warehouse_creation', SelectedDivisionFormset), ('final-warehouse_creation', FinalForm)], label=_(u"Warehouse creation"), url_name='warehouse_creation', @@ -99,6 +100,7 @@ warehouse_creation_wizard = WarehouseWizard.as_view([ warehouse_modification_wizard = WarehouseModificationWizard.as_view([ ('selec-warehouse_modification', WarehouseFormSelection), ("warehouse-warehouse_modification", WarehouseForm), + ('divisions-warehouse_modification', SelectedDivisionFormset), ('final-warehouse_modification', FinalForm)], label=_(u"Warehouse modification"), url_name='warehouse_modification', diff --git a/ishtar_common/wizards.py b/ishtar_common/wizards.py index 8fe39b054..2fbe30e0e 100644 --- a/ishtar_common/wizards.py +++ b/ishtar_common/wizards.py @@ -583,6 +583,12 @@ class Wizard(NamedUrlWizardView): old_m2ms = {} for model in whole_associated_models: related_model = getattr(obj, model + 's') + # manage through + if hasattr(related_model, 'through') and related_model.through: + related_set_name = str( + related_model.through.__name__ + '_set').lower() + if hasattr(obj, related_set_name): + related_model = getattr(obj, related_set_name) # clear real m2m if hasattr(related_model, 'clear'): old_m2ms[model] = [] @@ -609,6 +615,9 @@ class Wizard(NamedUrlWizardView): if value not in m2m_items[key]: if type(value) == dict: model = related_model.model + if hasattr(related_model, 'through') and \ + related_model.through: + model = related_model.through # not m2m -> foreign key if not hasattr(related_model, 'clear'): assert hasattr(model, 'MAIN_ATTR'), \ @@ -633,6 +642,11 @@ class Wizard(NamedUrlWizardView): else: if issubclass(model, models.BaseHistorizedItem): value['history_modifier'] = self.request.user + if hasattr(model, 'RELATIVE_MODELS') and \ + self.get_saved_model() in \ + model.RELATIVE_MODELS: + value[model.RELATIVE_MODELS[ + self.get_saved_model()]] = obj value = model.objects.create(**value) value.save() # check that an item is not add multiple times (forged forms) @@ -1003,8 +1017,18 @@ class Wizard(NamedUrlWizardView): if not hasattr(obj, key): return initial keys = c_form.form.base_fields.keys() - query = getattr(obj, key) - if not obj._meta.ordering: + related = getattr(obj, key) + # manage through + through = False + if hasattr(related, 'through') and related.through: + related_set_name = str( + related.through.__name__ + '_set').lower() + if hasattr(obj, related_set_name): + through = True + related = getattr(obj, related_set_name) + + query = related + if not through and not obj._meta.ordering: query = query.order_by('pk') for child_obj in query.all(): if not keys: |