Django模型:引用字段返回多种类型的模型

3
作为了解Django的项目,我正在尝试构建一个小游戏。
玩家有一个基地。基地可以拥有几种类型的物品。(车辆、防御、建筑)
我有3个静态表格,它们包含每个物品的第一级别的信息(在游戏中,这些值用于公式计算升级所需的东西)。我使用序列将所有这些物品插入这些不同的表格中,因此ID在表格之间是唯一的。
为了跟踪玩家在每个基地上拥有哪些物品,我有一个名为'Property'的表格。我想使用单个字段作为对物品ID的引用,并尝试使用Django模型实现此目标。
警告: 我对Django模型的了解非常有限,而且我已经困扰了几天了。
如果可能的话,应该如何完成?
我尝试在保存方法上使用注释来通过重写该字段中对象的ID的方式更改字段的值,然后在尝试“获取”该对象时通过ID查询对象,但我无法通过定义该字段为整数的模型的明显限制。-我希望它不会在调用save()之前验证。
def getPropertyItemID(func):
    """
    This method sets the referral ID to an item to the actual ID.
    """

    def decoratedFunction(*args):
        # Grab a reference to the data object we want to update.
        data_object=args[0]

        # Set the ID if item is not empty.
        if data_object.item is not None:
            data_object.item=data_object.item.id

        # Execute the function we're decorating
        return func(*args)

    return decoratedFunction

class Property(models.Model):
    """
    This class represents items that a user has per base.
    """

    user=models.ForeignKey(User)
    base=models.ForeignKey(Base)
    item=models.IntegerField()
    amount=models.IntegerField(default=0)
    level=models.SmallIntegerField(default=0)

    class Meta:
        db_table='property'

    @getPropertyItemID
    def save(self):
        # Now actually save the object
        super(Property, self).save()

我希望你能在这里帮助我。我想要的最终结果是能够使用类似以下的东西:

    # Adding - automatically saving the ID of item regardless of the class 
    # of item
    item = Property(user=user, base=base, item=building)
    item.save()

    # Retrieving - automatically create an instance of an object based on the ID 
    # of item, regardless of the table this ID is found in.
    building = Property.objects.all().distinct(True).get(base=base, item=Building.objects.all().distinct(True).get(name='Tower'))
    # At this point building should be an instance of the Building model

如果我完全错了,或者有其他更好的实现方法,请不吝赐教 :)
1个回答

4
我想您正在寻找一个通用关联(Generic Relationship):

请参考Django官方文档中的说明。

class Property(models.Model):
    user=models.ForeignKey(User)
    base=models.ForeignKey(Base)
    content_type = models.ForeignKey(ContentType) # Which model is `item` representing?
    object_id = models.PositiveIntegerField() # What is its primary key?
    item=generic.GenericForeignKey('content_type', 'object_id') # Easy way to access it.
    amount=models.IntegerField(default=0)
    level=models.SmallIntegerField(default=0)

这让您可以按照您提到的方式创建项目,但是您可能需要考虑一种不同的方法来过滤掉这些项目。


这太棒了。保存属性完美无缺。唯一的缺点是我必须使用“building = Property.objects.all().get(base=base, object_id=building.id)”而不是item=building,但它仍然可以正常工作。谢谢! - Cornelis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接