Лучший способ создать записи класса dict из цикла, чем locals()

Мне говорили, что использовать locals() для динамического создания переменных в Python — дурной тон. Тем не менее, я пишу класс (используя Django и Wagtail), и мне действительно нужно, чтобы эти вещи попадали в класс dict, то есть в локальные переменные оператора class, а не в отдельную структуру данных:

class BlogPage(Page):
    for language in languages:
        locals()['body_' + language] = RichTextField(blank=True)

Я не думаю, что смогу установить их после оператора класса с помощью setattr, потому что к тому времени обработка метакласса Django уже произойдет.

Есть ли способ лучше?


person mheavers    schedule 03.11.2017    source источник
comment
Возможно, воспользуйтесь словарем.   -  person клйкбаутоь мажа&    schedule 04.11.2017
comment
... хорошо, для оператора класса, особенно если метакласс выполняет какую-либо важную работу (что здесь кажется довольно вероятным), locals() на самом деле может быть оправдано (и, вероятно, действительно будет работать, в отличие от изменения locals() в функции).   -  person user2357112 supports Monica    schedule 04.11.2017
comment
Лучше не делать этого вообще и использовать какой-нибудь контейнер.   -  person juanpa.arrivillaga    schedule 04.11.2017
comment
Что такое RichTextField? Звучит похоже на Django, но, похоже, существует несколько библиотек, предоставляющих RichTextField для Django. Кроме того, что такое Пейдж?   -  person user2357112 supports Monica    schedule 04.11.2017
comment
RichTextField — это тип поля для Wagtail, CMS на основе Django. Страница — это конкретная запись в блоге. Таким образом, будет несколько Page класса BlogPage. Мне не нужно будет изменять эти поля форматированного текста, и на самом деле позже есть процесс content_panels = Page.content_panels + [ FieldPanel('body_en'),, где 'body_en' должен соответствовать объявлению RichTextField выше, поэтому, если он находится внутри dict, я не уверен, как это работает   -  person mheavers    schedule 04.11.2017
comment
Я внес несколько изменений, чтобы попытаться отличить этот вопрос от обычных вопросов о динамических именах переменных. Если у меня что-то не так, вы можете отредактировать снова или отменить мои изменения, если они полностью отключены.   -  person user2357112 supports Monica    schedule 04.11.2017
comment
@user2357112 user2357112 - да, я бы сказал, что это точно   -  person mheavers    schedule 04.11.2017


Ответы (1)


Проблема с тем, что разные языки являются атрибутами модели, заключается в том, что для изменения языков требуется миграция базы данных. Это не то, что вы когда-либо хотите сделать, если вы можете помочь.

Правильный способ решить эту проблему — использовать отдельную модель, которая сопоставляет страницу и язык с соответствующим содержимым.

class BlogPageTranslation(model.Model):
  language = TextField()
  blogpage = ForeignKey(BlogPage)
  content = RichTextField()

Затем при запросе страницы найдите переводы с нужным языком и разумным значением по умолчанию, а затем возьмите соответствующую строку.

xlatcontents = BlogPageTranslation.filter(blogpage=Page,
  language__in=[someLanguage, 'en'])
somethingsomething(xlatcontents, someLanguage)
person Ignacio Vazquez-Abrams    schedule 03.11.2017