简体   繁体   中英

adding / editing django generic foreign key objects

Model Device:

class Device(models.Model):
    device_code = models.CharField(max_length=64,unique=True)
    is_enabled = models.BooleanField(default=False)

    def __unicode__(self):
        return u'%s: %s' % (self.device_code, 'ENABLED' if self.is_enabled else 'DISABLED')

Model AttributeValues:

class AttributeValue(models.Model):
    attribute = models.ForeignKey(Attribute)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = GenericForeignKey('content_type', 'object_id')

    class Meta:
        abstract = True
        unique_together = (
            ('attribute', 'content_type','object_id'),
        )
        index_together = (
            ('content_type','object_id'),
        )
    @property        
    def formatted(self):
        """
        PLEASE SELECT RELATED ATTRIBUTE BEFORE USING THIS FUNCTION
        """
        return self.attribute.format % self.value

    def save(self,*args,**kwargs):
        if hasattr(self.content_object,'invalidate_cache') and callable(self.content_object.invalidate_cache):
            self.content_object.invalidate_cache()
        super(AttributeValue,self).save(*args, **kwargs)


    def __unicode__(self):
        return u'%s %s' % (self.attribute.name, self.value)

class NumericAttributeValue(AttributeValue):
    value = models.DecimalField(max_digits=12,decimal_places=4)


class LongTextAttributeValue(AttributeValue):
    value = models.TextField()

class ShortTextAttributeValue(AttributeValue):
    value = models.CharField(max_length=255)

class FileAttributeValue(AttributeValue):
    attribute_file = models.FileField(upload_to="attribute_imgs")

Model Attribute:

ATTRIBUTE_TYPE_CHOICES = (
    ('n','Numeric'),
    ('s','Short Text (255)'),
    ('m','Long Text')
)

class Attribute(models.Model):
        name = models.CharField(max_length=255)
        code = models.CharField(max_length=64,unique=True)
        attribute_type = models.CharField(max_length=1,choices=ATTRIBUTE_TYPE_CHOICES)
        sorting_order = models.PositiveIntegerField(default=0)
        show = models.BooleanField(default=False)
        format = models.CharField(max_length=64,default='%s')

        class Meta:
            ordering = ['sorting_order','name']

        def __unicode__(self):
            return self.name

In my device editing (adding) page, it needs to be able to create or select an attribute, then create (or edit / delete) an attribute value (could be a numeric value, long text value, short text value or a file) associated to this attribute, and the current (or new) device. How would you create a django formset for this kind of scenario?

I had to solve a similar problem and django-polymorphic worked for me.

If you define an abstract model as the parent, then it allows you to select any child models that the parent is based on in the Django admin interface (when selecting a foreign-key for example).

You will have to make some changes in your model & admin to get it working (for eg; you won't need GenericForeignKey ).

https://django-polymorphic.readthedocs.org/en/latest/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM