ListProperty пользовательских свойств - PullRequest
1 голос
/ 19 ноября 2010

Существует ли элегантный способ использования ListProperty для хранения подкласса db.Property типа?

Например, FuzzyDateProperty из в этом примере использует get_value_for_datastore() иmake_value_from_datastore() для преобразования его атрибутов в один int, который хранится в хранилище данных.Поскольку этот int является примитивом Python, кажется, что вы должны иметь возможность создать ListProperty из FuzzyDateProperty.Как?

В моем конкретном случае я определил класс и вспомогательные функции для аккуратной сериализации / десериализации его атрибутов.Я хотел бы инкапсулировать класс как db.Property вместо того, чтобы заставить обработчик обрабатывать отношения между классом и свойством Model.

Ответы [ 3 ]

2 голосов
/ 19 ноября 2010

Согласно классам типов и свойств doc

Хранилище данных App Engine поддерживает фиксированный набор типов значений для свойств объектов данных.Классы свойств могут определять новые типы, которые преобразуются в базовые типы значений и из них, а типы значений можно напрямую использовать с динамическими свойствами Expando и ListProperty моделями агрегатных свойств.

Мое чтение этого предполагает, что вы должны иметь возможность просто указать расширенный db.Property в качестве item_type для ListProperty.Но есть зарегистрированная проблема , которая предлагает иное.

Предполагая, что это не работает, я думаю, что следующая лучшая вещь, вероятно, состоит в том, чтобы создать подкласс ListProperty и вручную расширить его с помощью методов получения, установки иитераторы, основанные на функциях "get_value_for_datastore" и "make_value_from_datastore" для списков с членами "FuzzyDateProperty".

1 голос
/ 23 ноября 2010

В соответствии с рекомендациями @mjhm и @Nick, я подклассифицировал ListProperty для принятия любого класса. Я загрузил универсальную версию в GitHub с именем ObjectListProperty. Я использую его как более чистую альтернативу использованию параллельных ListProperty.

ObjectListProperty прозрачно сериализует / десериализует при получении и размещении модели. Он имеет внутренний метод сериализации, который работает для простых объектов, но может обрабатывать более сложные объекты, если они определяют свой собственный метод сериализации. Вот тривиальный пример:

from object_list_property import ObjectListProperty

class Animal():
    """ A simple object that we want to store with our model """
    def __init__(self, species, sex):
        self.species = species
        self.sex = sex if sex == 'male' or sex == 'female' else 'unknown'

class Zoo(db.Model):
    """ Our model contains of list of Animal's """
    mammals = ObjectListProperty(Animal, indexed=False)

class AddMammalToZoo(webapp.RequestHandler):
    def post(self):
        # Implicit in get is deserializing the ObjectListProperty items
        zoo = Zoo.all().get()

        animal = Animal(species=self.request.get('species'),
                        sex=self.request.get('sex') )

        # We can use our ObjectListProperty just like a list of object's
        zoo.mammals.append(animal)

        # Implicit in put is serializing the ObjectListProperty items
        zoo.put()
1 голос
/ 19 ноября 2010

Вы не можете сделать это - ListProperty ожидает базовый тип Python, а не класс свойства.Между тем классы свойств ожидают присоединения к модели, а не к другому свойству.

...