Невозможно определить сквозные отношения для двух моделей, которые используют базовый класс в Django - PullRequest
0 голосов
/ 31 мая 2019

У меня есть «заданная» модель, которая имеет отношение «многие ко многим» к модели «Предмет». Проблема в том, что 'set' является подклассом Item (все является Item в проекте).

Это работает нормально, пока я не попытаюсь создать сквозное отношение к промежуточной модели, называемой «заказ», которую я определяю, чтобы я мог заказать «Предметы» внутри «Комплекта».

Когда я пытаюсь определить отношение, я получаю эту ошибку:

ERRORS:
curate.Set.items_: (fields.E001) Field names must not end with an underscore.
curate.order.set: (fields.E304) Reverse accessor for 'order.set' clashes with reverse accessor for 'order.item'.
        HINT: Add or change a related_name argument to the definition for 'order.set' or 'order.item'.

Я пытался добавить related_name в Order.set, а также Order.item, но, похоже, это не работает. Я могу сделать миграцию счастливой, но когда я пытаюсь мигрировать, я получаю сообщение об ошибке:

ValueError: Cannot alter field curate.Set.items into curate.Set.items - they are not compatible types (you cannot alter to or from M2M fields, or add or remove through= on M2M fields)

models.py


class Item(models.Model, AdminVideoMixin):

    title = models.TextField(max_length=5000)
    slug = models.SlugField(max_length=5000, default='')
   ...

class Video(Item):
    video_embed = EmbedVideoField(max_length=500)
    ...

class Article(Item):
    authors = models.CharField(max_length=10000)
    ...

class Podcast(Item):
    categories = models.CharField(max_length=5000, null=True, blank=True,)
    ...

class Episode(Item):
    author = models.CharField(max_length=10000, null=True,blank=True,)
    ...

class Set(Item):
    items = models.ManyToManyField(Item, related_name='setItems', max_length=5000, through='Order')
    front_page = models.BooleanField(max_length=300, blank=False, default=False, null=False)

class order(models.Model):
    item = models.ForeignKey(Item, on_delete=models.CASCADE,)
    set = models.ForeignKey(Set, on_delete=models.CASCADE,)
    order = models.CharField(max_length=64, default=0)

1 Ответ

1 голос
/ 31 мая 2019

Нельзя изменить поле ManyToMany для использования отношения through после его создания. Это связано с тем, что сквозная таблица теперь будет содержать дополнительные поля, которые не могут быть заполнены стандартными отношениями ManyToMany (это та же самая причина, по которой вы не можете использовать add, clear, remove, delete, когда используя сквозную таблицу). Вам нужно будет создать новое поле ManyToMany в Set, которое использует сквозное отношение, а затем заполнить его данными из Set.items перед удалением Set.items.

Документы по сквозным таблицам

Если вам нужно новое поле с именем items, вы можете сделать следующее:

  • Измените items на items_old в модели Set, вам также потребуется изменить related_name, если вы хотите, чтобы оно было таким же (создайте и запустите миграцию)
  • Добавить новое поле items со сквозным отношением (создать и запустить миграцию)
  • Заполните новое поле items данными из items_old
set_items = Set.objects.filter(items__isnull=False)
Order.objects.bulk_create([
    Order(item=item, set=s)
    for s in set_items
    for item in s.items.all()
])
  • Удалить items_old из Set

NB. Подобно тому, как katoozi упоминается в его комментарии, вы, вероятно, не должны иметь полей с именем set

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...