Модели Django: поле ссылки возвращает несколько типов моделей - PullRequest
2 голосов
/ 03 ноября 2011

В качестве проекта по выяснению Джанго я пытаюсь построить небольшую игру.

У игрока есть база.База имеет несколько типов предметов, которые она может скрывать.(Vehicle, Defense, Building).

У меня есть 3 статические таблицы, которые содержат информацию для первого уровня каждого предмета (в игре эти значения используются в формулах для расчета вещей для улучшений).Я использовал последовательность, чтобы вставить все эти элементы в эти разные таблицы, чтобы идентификаторы были уникальными для всех таблиц.

Чтобы отслеживать, какие предметы есть у игрока в каждой базе, у меня есть таблица «Свойство».Я хочу использовать одно поле в качестве ссылки на идентификатор элемента и пытаться добиться этого с помощью моделей Django.

Предупреждение: мои знания о моделях Django довольно ограничены, и я застрял счерез несколько дней.

Возможно ли это, и если да, то как это можно сделать?

Я попытался использовать аннотации в методе сохранения, чтобы изменить значение поля, перезаписав поле с помощьюid этого объекта, прежде чем пытаться запросить объект по id при попытке «получить» объект, однако я не могу обойти очевидное ограничение модели при определении этого поля как Integer - я надеялся, что оно не будет проверятьсяпока я не позвонил 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 Ответ

3 голосов
/ 03 ноября 2011

Я думаю, что вы ищете Родовые отношения :

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)

Это позволяет вам создавать элементы, как вы упомянули, однако вам, вероятно, придется взглянуть на другой способ фильтрации этих элементов.

...