mercredi 6 mai 2015

Replace ArrayField for several fields from other models: ArrayField(ForeignKey) emulation in django-admin

I want to store model fields as array of foreign keys to other atomic-Models. It makes model more flexible: I can add/remove/inherit(if it's tree node) any of predefined properties without programming.

Let's start with atomic-Models. It contain some classified properties.

class Liquid(models.Model):
    volume = models.DecimalField(max_digits=12, decimal_places=6)

class Granular(models.Model):
    weight = models.DecimalField(max_digits=16, decimal_places=9)

class Serial(models.Model):
    lot_number = models.CharField(max_length=16)
    estimated_release_time = models.DateTimeField()
    deadline_time = models.DateTimeField())

I want to emulate the following code. It's not valid because:
1. I want to store foreign keys to several models (GenericForeignKey can help);
2. ArrayField doesn't support array of foreign keys yet;

class Entity(models.Model):
        arr = ArrayField(models.ForeignKey(DifferentAtomicModels))

Emulation is the following. Where even numbers is pk of django.contrib.contenttypes.models.ContentType, odd numbers is pk of atomic-Model (atomic-model obtained from the previous even number).

class Entity(models.Model):
    arr = ArrayField(models.IntegerField(), null=True, blank=True)

Well, in in django-admin changelist_view and changeform_view I want to replace arr field with the fields obtained from it.

What is the way to achieve this? Where it's better to intervene to django-admin behaviour (override formfield, make custom widget, smth. else...)?

P.S. What kind of emulation is better?

class Entity(models.Model):
    em01 = ArrayField(models.IntegerField())  # "ContentType_pk", "Model_pk", ...
    em02 = ArrayField(ArrayField(models.IntegerField(), size=2))  # "ContentType_pk", "Model_pk", ...
    em03 = ArrayField(ArrayField(models.CharField(), size=2))  # "Model_name", "Model_pk", ...
    em11 = HStoreField()  # {"ContentType_pk": "Model_pk"}
    em12 = HStoreField()  # {"Model_name": "Model_pk"}

Aucun commentaire:

Enregistrer un commentaire