About | Blog | xapy

All articles, tagged with “python”

Django ManyToMany field со своими именами колонок

Некоторое время назад столкнулся с задачей, близкой к описанной в джанговской доке Integrating with a legacy database. В контексте общей задачи, прикрутить джанго-админку к существующей БД, возник небольшой вопрос, ответ на который в Сети тогда так и не нашёл. Итак, вопрос: имеем табличку с many-to-many маппингом model1 <-> model2. Хочется это описать в терминах привычных для django отношений между моделями. Разумеется, описывалось бы это лучше всего стандартным полем ManyToManyField, если бы не одно “но” — по умолчанию такое поле создаёт таблицу (её название настраиваемо с помощью keyword-argument db_table) с полями, названными соответственно model1_id и model2_id. Так как схема БД задана заранее и не подлежит изменению, а названия полей в нашей таблице, разумеется, с упомянутыми не совпадают, потребовалось слегка нестандартное решение. Т.о. постановка задачи: есть модель Product с полем guid и модель Category с полем id. По умолчанию имеем таблицу с полями product_id, category_id, хотим: guid, manual_classification. И, собственно, простое решение:

class ManyToManyFieldWithCustomColumns(models.ManyToManyField):
    def _get_m2m_column_name(self, related):
        return related.model._meta.pk.db_column
    def _get_m2m_reverse_name(self, related):
        return self.db_column

После этого в модели Product определяем нужное поле в виде:

categories = ManyToManyFieldWithCustomColumns(Category,db_column='manual_classification',              
                                              db_table='product_classification')

Уверен, должно найтись и более элегантное решение, например усовершенствование в сторону имени колонки, обозначающей ключ текущей модели (в моём случае взял db_column от ключа, не меняя). Кто может предложить — велкам в коменты :)

pastebin под рукой

Простенький скрипт для отправки файлов в пастбин. Может кому пригодится. Код — внутри

 continue reading