Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Сделать совместимым с south #1

@daevaorn

Description

@daevaorn

Чтоб south'у жилось легче, нужно добавить вот этот метод к CompositionField:

def south_field_triple(self):
    "Returns a suitable description of this field for South."
    # We'll just introspect the _actual_ field.
    from south.modelsinspector import introspector
    field_class = self._c_native.__class__.__module__ + "." + self._c_native.__class__.__name__
    args, kwargs = introspector(self._c_native)
    # That's our definition!
    return (field_class, args, kwargs)

Он возвращает интроспектору native элемент, так что тому не приходится гадать и создавать непонятно что.

Без этого глючат миграции, например

class ForeignCountField(CompositionField):
def init(self, model, link_back_name, link_to_foreign_name, filter={}, native=None, signal=None):
self.model = model
self.do = lambda object, foreign, signal: getattr(object, link_to_foreign_name).filter(**filter).count()
self.instance_getter = lambda foreign: getattr(foreign, link_back_name)
self.native = native or models.PositiveIntegerField(default=0)
self.signal = signal or (models.signals.post_save, models.signals.post_delete)

    self.internal_init(
        native = self.native,
        trigger = dict(
            on = self.signal,
            sender_model = self.model,
            do = self.do,
            field_holder_getter = self.instance_getter
        )
    )

class Book(models.Model):
author = models.ForeignKey('Author')

class Author(models.Model):
books_count = ForeignCountField(Book, 'author', 'book_set')

Миграция про добавлении поля books_count создается успешно, но применить ее не выходит, т.к. обработчики присоединяются к сигналам post_save и post_delete не для конкретной модели Book, а для всех моделей сразу (параметр sender=None). Наверное, это связано с "заморозкой" моделей в South и с тем, что он что-то пытается создать своим FakeORM и, видимо, на момент создания ForeignCountField класс Book оказывается недоступным.

Если ему явно указать, что там за тип столбца в базе (добавив south_field_triple), то он замораживает поле не как ForeignCountField, а как PositiveIntegerField, и все начинает работать нормально, сигналы подцепляются к Book и все ок.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions