开发者

Django Model field with multiple types?

开发者 https://www.devze.com 2023-03-11 15:50 出处:网络
I have the following (simplified) models: class Structure(models.Model): name=models.CharField(max_length=100, unique=True)

I have the following (simplified) models:

class Structure(models.Model):
name=models.CharField(max_length=100, unique=True)

class Unit(models.Model):
name=models.CharField(max_length=100, unique=True)

Each model, also has a builtFrom field, which shows what the item is built from, for example:

class Unit(models.Model):
name=models.CharField(max_length=100, unique=True)
builtFrom=models.ForeignKey(Structure)

However, builtFrom can be populated from either a Unit type, or a Structure type. Is there an easy way to represent this in my models?

The only thing I can think of is to have a separate model开发者_运维知识库, like so:

class BuiltFromItem(models.Model):
structure=models.ForeignKey(Structure)
unit=models.ForeignKey(Structure)


class Unit(models.Model):
name=models.CharField(max_length=100, unique=True)
builtFrom=models.ForeignKey(BuiltFromItem)

And then have one of the BuiltFromItem fields just be null. Then, when I need the data, figure out whether it is a structure or unit that it is built from. Is there a better solution for this?


You want what the Django docs refer to as a "generic relation". Support for them is built into Django.


Generic relation is probably the best approach, yet it can be a little problematic, if you're planning to manage such models via admin panel. You would then have to add a ModelInline to the models, that generic relation is pointing to, but as far as I know (correct me if I'm wrong), there's no convenient way of picking related object from the other side (from model, where relation is defined), other than choosing model class and manually typing instance primary key.

Picking the best solution actually depends on structure of your models and on what they have in common. Another idea I have, is to use Multi-table inheritance, by defining some BasicObject that is a parent object to Structure and Unit models:

class BasicObject(models.Model):
    name=models.CharField(max_length=100, unique=True)
    #other common data
    builtFrom=models.ForeignKey('BasicObject')

class Structure(BasicObject):
    #data specific to Structure

class Unit(BasicObject):
    #data specific to Unit

Now all Structure and Unit object will also be BasicObject instances, and you will be able to populate builtFrom field with proper BasicObject instance. It makes queries more expensive, because data is divided into two diffrent tables, so you should consider if this approach is beneficial in your case.

0

精彩评论

暂无评论...
验证码 换一张
取 消