Миграция Django South не может получить доступ к метаатрибуту пользовательской модели

У меня есть приложение Django, которое я создал и которое использует Django Guardian для управления разрешениями на уровне объектов и Django South для управления миграциями. Я создал модельный миксин, который позволяет моделям определять права доступа на уровне объекта, которые будут назначаться при их создании, с использованием пользовательского мета-атрибута. Так, например, Message Модель может выглядеть так:

class Message(AutoUserPermissionsMixin, models.Model):
  sender = models.ForeignKey(User)
  recipient = models.ForeignKey(User)
  text = models.TextField(blank=True)

  class Meta:
    permissions = (
      ('view_message', 'Can view message'),
      ('respond_to_message', 'Can respond to message'),
    )

    user_permissions_to_add = {
      'recipient' : ('view_message', 'respond_to_message',),
      'sender' : ('view_message',)
    }

AutoUserPermissionsMixin определяет обычай save() который читает метаданные модели, чтобы узнать, какие разрешения на уровне объекта должны быть назначены какому полю из user_permissions_to_addи выполняет задание. Я добавил настраиваемое поле Meta, выполнив это в верхней части файла, где я определяю AutoUserPermissionsMixin:

from django.db import models
models.options.DEFAULT_NAMES += ('user_permissions_to_add',)

Проблема в том, что я пытаюсь выполнить миграцию данных на юг, чтобы создать ряд новых экземпляров модели, а он не назначает разрешения на уровне объектов, потому что пользовательские save() методы не обрабатываются при миграции.

Теперь я могу использовать тот же метод, который используется в пользовательских save() попытаться применить разрешения в модели, которая sync_object_permissions(instance, permissions), Я хочу читать разрешения в любом состоянии, в котором они находятся на Meta во время миграции, а не жестко кодировать их в процессе миграции. Однако при попытке позвонить sync_object_permissions(message_instance, permissions=message_instance._meta.user_permissions_to_add)Юг выдает ошибку:

AttributeError: 'Options' object has no attribute 'user_permissions_to_add'

Так что по какой-то причине Meta не обновляется с моим кастомом user_permissions_to_add атрибут во время миграции. Как я могу убедиться, что он есть на Мете в миграции?

1 ответ

Юга modelinspector может быть изменено, чтобы вырвать ваше дополнительное поле на Meta, чтобы это поле было доступно во время миграции.

Вот код, который я использовал (поместите его в ваш файл models.py или в другой импортируемый файл):

#make South record the Meta field "my_special_field" in its orm freezes
import south.modelsinspector as mi
mi.meta_details['my_special_field'] = ['my_special_field', {'default': None, 'ignore_missing': True}]

Обратите внимание, что если вы не включите 'ignore_missing': True тогда South будет выдавать исключение, когда обрабатывает любые модели, которые не включают my_special_field в свои мета-опции

Вы можете проверить другие мета-поля, которые уже записаны Югом, посмотрев другие поля на south.modelsinspector.meta_details

Другие вопросы по тегам