2013-11-24 2 views
3

Я прочитал, что имя таблицы в Django можно настроить, используя Meta Options. Мне интересно, как использовать параметр db_table, чтобы продолжать использовать имя приложения, но слегка модифицировать имя модели без жесткого кодирования имени приложения.Изменить имя таблицы в Django

Например, из учебника Django имя приложения - «опросы», а имя модели - «опрос». Допустим, я хочу, чтобы таблица называлась «polls_mypoll» вместо «polls_poll». Вот то, что я пытался, но внешний класс не может получить доступ (опрос не определен)

class Poll(models.Model): 
    question = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 

    class Meta: 
     db_table = "%s_%s" % (Poll._meta.app_label, "mypoll") 

Точно так же, если я хотел определить db_table явно, чтобы быть просто polls_poll по умолчанию? Я знаю, что могу просто оставить класс Meta полностью, и это имя по умолчанию будет использоваться, но что, если я хочу быть откровенным об этом?

class Poll(models.Model): 
    question = models.CharField(max_length=200) 
    pub_date = models.DateTimeField('date published') 

    class Meta: 
     db_table = "%s_%s" % (Poll._meta.app_label, Poll._meta.model_name) 

Это не работает, потому что Poll не определен внутри Meta.

+0

Это не значит, что опрос должен быть объявлен _inside_ Meta доступным; он просто не был полностью проанализирован тем временем, когда Meta анализируется. – XORcist

ответ

0

Исключение, которое вы получаете, Poll is not defined, вызвано оператором db_table = "%s_%s" % (Poll._meta.app_label, Poll._meta.model_name), ссылающимся на класс Poll, пока он еще сконструирован (еще не вставлен в глобальную область). Если вы хотите использовать ссылки на Poll в db_table, рассмотрите возможность написания собственного метакласса, который наследуется от ModelBase, и правильно устанавливает значение _meta.db_table. В этот момент имя Poll будет недоступно, но фактический объект будет построен и у вас под рукой, чтобы манипулировать.

+0

Возможно, вы могли бы сделать db_table a @property в классе Meta, чтобы лениво генерировать/искать имя таблицы (внутри этого производного метакласса). – XORcist

+0

@ XORcist, ну да - он мог определить, является ли это значение вызываемым - если это так, замените его на результат 'callable (class)'. Что касается '@ property', вам нужно будет скопировать-вставить этот метод в другие модели, если это необходимо, поскольку нет способа передать базовый класс модели (который я могу сейчас думать) на полученный Meta-класс во время построения. –

+0

@XORcist, также обратите внимание, что '_meta' получает копию того, что объявил класс' Meta' (_not instance_), поэтому '_meta' будет объектом' property', а не дескриптором. –

Смежные вопросы