Как узнать, является ли столбец модели внешним ключом? - PullRequest
11 голосов
/ 09 апреля 2010

Я динамически храню информацию в базе данных в зависимости от запроса:

// table, id and column are provided by the request
table_obj = getattr(models, table)
record = table_obj.objects.get(pk=id)

setattr(record, column, request.POST['value'])

Проблема в том, что request.POST ['value'] иногда содержит первичный ключ внешней записи (то есть целое число), тогда как Django ожидает, что значение столбца будет объектом типа ForeignModel:

Невозможно назначить «u'122»: «ModelA.b» должен быть экземпляром «ModelB».

Теперь, есть ли элегантный способ динамически проверить, является ли b столбцом, содержащим внешние ключи, и с какой моделью эти ключи связаны? (Чтобы я мог загрузить внешнюю запись по ее первичному ключу и назначить ее для ModelA?) Или Django не предоставляет такую ​​информацию программисту, поэтому мне действительно нужно испачкать руки и использовать isinstance () на иностранной ключевой столбец?

Ответы [ 4 ]

13 голосов
/ 09 апреля 2010

Вы можете использовать get_field_by_name для объекта модели _meta:


from django.db.models import ForeignKey

def get_fk_model(model, fieldname):
    '''returns None if not foreignkey, otherswise the relevant model'''
    field_object, model, direct, m2m = model._meta.get_field_by_name(fieldname)
    if not m2m and direct and isinstance(field_object, ForeignKey):
        return field_object.rel.to
    return None

Предполагая, что у вас есть класс модели MyModel, вы бы использовали это так:


fk_model = get_fk_model(MyModel, 'fieldname')

3 голосов
/ 17 марта 2016

Простой один вкладыш, чтобы найти все отношения с другими models, которые существуют в model:

In [8]: relations = [f for f in Model._meta.get_fields() if (f.many_to_one or f.one_to_one) and f.auto_created]

выше даст list всех models с их relations.

Пример:

In [9]: relations
Out[9]:
[<ManyToOneRel: app1.model1>,
 <ManyToOneRel: app2.model1>,
 <OneToOneRel: app1.model2>,
 <OneToOneRel: app3.model5>,
 <OneToOneRel: app5.model1>]
1 голос
/ 12 июня 2012

Я столкнулся с тем же вариантом использования, и принятый ответ не работал для меня напрямую Я использую Django 1.2, если это актуально. Вместо этого я использовал метод get_field_by_name следующим образом.

def get_foreign_keys(self):
        foreign_keys = []
        for field in self._meta.fields:
            if isinstance(self._meta.get_field_by_name(field.name)[0], models.ForeignKey):
                foreign_keys.append(field.name)

        if not foreign_keys:
            return None
        return foreign_keys

Это метод определения внутри класса. В моем случае мне нужны имена полей ForeignKey. Ура! * * 1005

0 голосов
/ 09 апреля 2010

Изучите поля "ModelChoiceField". Могут ли они решить вашу проблему, вставив внешние ключи в формы для вас; вместо того, чтобы делать это самостоятельно.

http://docs.djangoproject.com/en/1.1/ref/forms/fields/#fields-which-handle-relationships

record = forms.ModelChoiceField(queryset=table_obj.objects.all())
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...