Получить поля модели в Django
учитывая модель Django, я пытаюсь перечислить все ее поля. Я видел несколько примеров этого с использованием атрибута _meta model, но разве подчеркивание перед meta не указывает, что атрибут _meta является частным атрибутом и не должен быть доступен напрямую? ... Потому что, например, макет _meta может измениться в будущем и не быть стабильным API?
_meta является исключением из этого правила? Является ли он стабильным и готовым к использованию или он считается плохим практика, чтобы получить к нему доступ? Или есть функция или какой-то другой способ интроспекции полей модели без использования атрибута _meta? Ниже приведен список некоторых ссылок, показывающих, как это сделать с помощью атрибута _meta
любой совет высоко ценится.
django object get / set field
http://www.djangofoo.com/80/get-list-model-fields
Как интроспектировать поля модели django?
7 ответов:
_metaявляется частным, но он относительно стабилен. Предпринимаются усилия по его формализации, документированию и удалению подчеркивания, что может произойти до 1.3 или 1.4. Я предполагаю, что будут предприняты усилия, чтобы обеспечить обратную совместимость, потому что многие люди все равно используют его.если вас особенно беспокоит совместимость, напишите функцию, которая принимает модель и возвращает поля. Это означает, что если что-то изменится в будущем, вам нужно только измените одну функцию.
def get_model_fields(model): return model._meta.fieldsЯ считаю, что это вернет список
Fieldобъекты. Чтобы получить значение каждого поля из экземпляра, используйтеgetattr(instance, field.name).Update: участники Django работают над API для замены объекта _Meta в рамках Google Summer of Code. Смотрите:
- https://groups.google.com/forum/#! тема/django-разработчики / hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api
Я знаю, что этот пост довольно старый, но я просто хотел сказать всем, кто ищет то же самое, что есть общественные и официального API для этого:
get_fields()иget_field()использование:
fields = model._meta.get_fields() my_field = model._meta.get_field('my_field')
Это то, что делается самим Django при построении формы из модели. Он использует атрибут _meta, но, как отметил Бернхард, он использует оба _meta.поля и _meta.many_to_many. Глядя на Джанго.формы.модели.fields_for_model, вот как вы могли бы это сделать:
opts = model._meta for f in sorted(opts.fields + opts.many_to_many): print '%s: %s' % (f.name, f)
поля модели, содержащиеся в _meta, перечислены в нескольких местах в виде списков соответствующих объектов поля. Возможно, будет проще работать с ними как со словарем, где ключи-это имена полей.
на мой взгляд, это самый безвозвратный и выразительный способ сбора и организации объектов модельного поля:
def get_model_fields(model): fields = {} options = model._meta for field in sorted(options.concrete_fields + options.many_to_many + options.virtual_fields): fields[field.name] = field return fields(см. это пример использования в Django.формы.модели.fields_for_model.)
теперь есть специальный метод - get_fields ()
>>> from django.contrib.auth.models import User >>> User._meta.get_fields()Он принимает два параметра, которые можно использовать для управления возвращаемыми полями:
include_parents
True по умолчанию. Рекурсивно включает поля, определенные в родительских классах. Если установлено значение False, get_fields () будет искать только поля, объявленные непосредственно в текущей модели. Поля из моделей, которые непосредственно наследуются от абстрактных моделей или прокси-классы считаются локальными, а не родительскими.
include_hidden
False по умолчанию. Если установлено значение True, get_fields () будет включать поля, которые используются для поддержки функциональности других полей. Это также будет включать любые поля, имеющие related_name (например, ManyToManyField или ForeignKey), которые начинаются с "+"
get_fields()возвращает atupleи каждый элементModel fieldтип, который не может быть использован непосредственно в виде строки. Итак,field.nameвозвращает имя поля
my_model_fields = [field.name for field in MyModel._meta.get_fields()]
Приведенный выше код вернет список, содержащий имя всех полей
примерIn [11]: from django.contrib.auth.models import User In [12]: User._meta.get_fields() Out[12]: (<ManyToOneRel: admin.logentry>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: password>, <django.db.models.fields.DateTimeField: last_login>, <django.db.models.fields.BooleanField: is_superuser>, <django.db.models.fields.CharField: username>, <django.db.models.fields.CharField: first_name>, <django.db.models.fields.CharField: last_name>, <django.db.models.fields.EmailField: email>, <django.db.models.fields.BooleanField: is_staff>, <django.db.models.fields.BooleanField: is_active>, <django.db.models.fields.DateTimeField: date_joined>, <django.db.models.fields.related.ManyToManyField: groups>, <django.db.models.fields.related.ManyToManyField: user_permissions>) In [13]: [field.name for field in User._meta.get_fields()] Out[13]: ['logentry', 'id', 'password', 'last_login', 'is_superuser', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'groups', 'user_permissions']
Comments