Как проверить тип поля «многие ко многим» в Django? - PullRequest
6 голосов
/ 17 мая 2010

Как вы можете проверить тип поля «многие ко многим» в django?

Я хотел сделать это так:

import django  
field.__class__ == django.db.models.fields.related.ManyRelatedManager

Это не работает, потому что класс ManyRelatedManager не может быть найден. Но если я сделаю field.__class__, то получится django.db.models.fields.related.ManyRelatedManager

Почему это относится к классу, который, кажется, не существует и как я могу заставить его работать?

Большое спасибо за вашу помощь.

Ответы [ 4 ]

14 голосов
/ 17 мая 2010

Вы должны быть в состоянии проверить это как строку.

field.__class__.__name__ == 'ManyRelatedManager'
5 голосов
/ 17 мая 2010

Если у вас уже есть экземпляр поля, вы можете просто сделать:

if isinstance(field, ManyToManyField):
    pass // stuff

Если у вас есть только связанный экземпляр диспетчера, вы можете отменить поиск экземпляра поля:

>>> print fm
<class 'django.db.models.fields.related.ManyRelatedManager'>
>>> print fm.instance._meta.get_field_by_name('fieldnamehere')
(<django.db.models.fields.related.ForeignKey: fieldnamehere>, None, True, False)

Это было проверено только на Django 1.5

0 голосов
/ 16 ноября 2017

(с использованием Django 1.11)

Этот вопрос стал запутанным, потому что сообщаемое поведение не является современным поведением для смежной области. Пример здесь, где JobTemplate - это класс модели, а credentials - это поле, связанное со многими ко многим:

>>> JobTemplate._meta.get_field('credentials').__class__
 django.db.models.fields.related.ManyToManyField

Отличается ли это, если мы проверяем _meta объекта?

>>> JobTemplate.objects.first()._meta.get_field('credentials').__class__
django.db.models.fields.related.ManyToManyField

нет.

Так вот, когда я вставляю то, что я считаю наиболее вероятным сценарием прихода сюда кого-то. У вас есть это:

>>> JobTemplate.objects.first().credentials
<django.db.models.fields.related_descriptors.ManyRelatedManager at 0x6f9b390>

Обратите внимание, это то, что было у ОП.

Я оговорю, что связанной моделью является Credential. Я могу проверить, связан ли это с диспетчером учетных данных!

>>> isinstance(JobTemplate.objects.first().credentials, Credential.objects.__class__)
True

Поля ManyToMany могут быть очень трудными для обработки, потому что атрибут убивает себя и заменяет себя подклассом менеджера. Вы также можете сопоставить эту информацию с полем, полученным из get_field('credentials'), чтобы быть более уверенным. Вышеупомянутая проверка isinstance может также ошибочно подобрать других менеджеров, которые вы установили в модели. Тем не менее, это все еще является ценным тестом, чтобы выяснить, «крякает» ли ваш атрибут «как» поле ManyToMany этой конкретной связанной модели.

0 голосов
/ 17 мая 2010

Я не совсем уверен, чего вы пытаетесь достичь, но я думаю, вам лучше взглянуть на атрибут _meta вашей модели для определения класса поля!проверить _meta.fields и _meta.many_to_many!

Вы можете сделать что-то вроде:

field_class = [f for f in yourmodel._meta.many_to_many if f.name=='yourfield'][0].__class__
...