0

Я использую потоковое поле Wagtail, чтобы пользователи могли загружать и ссылаться на документы в интерфейсе редактора. Первоначально я пытался использовать внешний ключ, как указано в документации, и как все другие примеры, которые я видел. Я продолжал получать сообщение об ошибке при выполнении миграций, в которых wagtail document не имеет свойства «set name». Поэтому я решил не использовать внешний ключ, потому что эти документы необязательно должны относиться к отношениям «один ко многим» для наших целей. Поэтому в моей модели я не использую внешний ключ для всех полей с помощью DocumentChooserBlocks, и все работает нормально. Я недопонимаю «внешний ключ» и ошибаюсь (или плохо разбираюсь в БД). Вот моя рабочая модель для этого:Нужно ли иметь документ-чей-то замок для внешнего ключа?

class AgendaPage(Page): 
author= models.CharField(max_length=255) 
date = models.DateField('Post date') 
mtg_date = models.DateField(default=datetime.date.today) 
mtg_time = models.CharField(max_length=255, default ='10:00 AM') 
full_video_url-models.CharField(required =False) 
###full_audio = DocumentChooserBlock(required=False) 
###mtg_transcript = DocumentChooserBlock(required=False) 
]) 
agenda = StreamField([ 
    ('agenda_item', blocks.StreamBlock([ 
     ('item_title', blocks.TextBlock()), 
     ('item_text', blocks.TextBlock()), 
     ('mtg_doc', blocks.StructBlock([ 
      ('mtg_doc_upload', DocumentChooserBlock(required=True)), 
      ('submitted_late', blocks.BooleanBlock(required=False, help_text='Submitted Late')), 
      ('heldover', blocks.BooleanBlock(required=False, help_text='Held Over')), 
      ('heldover_from', blocks.DateBlock(required=False, help_text="Held Over From")), 
     ])), 
     ('item_audio', DocumentChooserBlock(required=False)), 
    ])) 
]) 




content_panels = Page.content_panels + [ 
    FieldPanel('author'), 
    FieldPanel('date'), 
    FieldPanel('mtg_date'), 
    FieldPanel('mtg_time'), 
    StreamFieldPanel('agenda'), 

] 

Кроме того, в двух закомментированных линиях в модели, я пытаюсь иметь DocumentChooserBlock, которое не внутри streamfield (без внешнего ключа) Я знаю, что этот синтаксис скорее всего, неверно, поскольку все примеры, которые я вижу, определяют ключ forein в определении модели, а затем ссылаются на панель DocumentChooser в определении панелей. Возможно ли (или желательно) сделать это без внешнего ключа?

ответ

1

DocumentChooserBlock никогда не используется с внешним ключом. Есть два различных метода прикрепления документов к страницам, и вы выбираете один или другой:

  • ForeignKey на документ, с DocumentChooserPanel в content_panels. Это будет использоваться, если у вас есть отношение «один к одному» или «много-к-одному» с страниц на документы; например, ProductPage, где продукт имеет листы данных PDF. Это создает формальную связь между двумя объектами на уровне базы данных.

  • A StreamField с DocumentChooserBlock в нем. Это используется для более гибких схем, где ссылка документа может отображаться в любой позиции вниз по странице. На уровне базы данных нет формальной ассоциации - с точки зрения базы данных StreamField - это просто бесплатный текст. Это означает, что нет необходимости в ForeignKey.

+0

Как создать DocumentChooserPanel, который не находится в потоковом поле, у которого нет внешнего ключа? – JohnnyP

+1

Вы бы этого не сделали. Внешний ключ - это то, что позволяет базе данных знать, что страница X связана с документом Y. Если вы действительно хотите избежать внешнего ключа, вы можете использовать простой Django FileField (https: //docs.djangoproject. com/en/1.10/ref/models/fields/# django.db.models.FileField) вместе с полем FieldPanel, но это намного примитивнее (вы просто получите простое поле «загрузить», а не интерфейс выбора всплывающих окон). – gasman

+0

Я собираюсь выйти на конечность, задаю этот вопрос: почему это нормально, чтобы не иметь внешний ключ в загрузке документа в потоковое поле? Все эти ответы воспитывали меня и приближали меня к решению, но я все еще явно что-то недопонимаю. – JohnnyP