2010-09-05 6 views
82

Учитывая модель Django, я пытаюсь перечислить все ее поля. Я видел некоторые примеры этого, используя атрибут модели _meta, но не подчеркивает ли перед meta указание, что атрибут _meta является частным атрибутом и к нему не следует обращаться напрямую? ... Так как, например, макет _meta может измениться в будущем и не будет стабильным API?Получить поля модели в Django

Является ли _meta исключением из этого правила? Является ли он стабильным и готовым к использованию или считается плохой практикой для доступа к нему? Или есть функция или какой-либо другой способ интроспекции полей модели без использования атрибута _meta? Ниже приведен список некоторых ссылок, показывающих, как это сделать, используя атрибут _meta.

Любые советы очень ценятся.

django object get/set field

http://www.djangofoo.com/80/get-list-model-fields

How to introspect django model fields?

+0

возможным дубликатом [Джанго: получить список модельных полей?] (HTTP: // StackOverflow .com/questions/3106295/django-get-list-of-model-fields) – Anto

ответ

113

_meta является частным, но это относительно стабильным. Предпринимаются усилия по его формализации, документированию и устранению подчеркивания, которое может произойти до 1.3 или 1.4. Я предполагаю, что усилия будут направлены на то, чтобы обеспечить совместимость в обратном направлении, потому что в любом случае многие люди его используют.

Если вы особенно обеспокоены совместимостью, напишите функцию, которая берет модель и возвращает поля. Это означает, что если что-то изменится в будущем, вам нужно будет только изменить одну функцию.

def get_model_fields(model): 
    return model._meta.fields 

Я считаю, что это вернет список Field объектов. Чтобы получить значение каждого поля из экземпляра, используйте getattr(instance, field.name).

Обновление: участники Django работают над API, чтобы заменить объект _Meta как часть Google Summer of Code. См:
- https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
- https://code.djangoproject.com/wiki/new_meta_api

+40

Вы также должны знать о факте, что, если вам также нужны поля «многие-ко-многим», вам нужно получить доступ к 'model._meta. many_to_many'! –

+1

Спасибо. Хорошо знать, что другие люди используют _meta. Мне нравится идея иметь функцию обертки. Lazerscience, спасибо. Полезно знать, что есть хороший метод для получения полей many_to_many. Joe –

+1

def get_model_fields (self): return self._meta.fields использовал это, чтобы легко вернуть все поля модели ... Большое спасибо ... – garmoncheg

8

Это то, что делается самим Джанго при создании формы из модели. Он использует атрибут _meta, но, как заметил Бернхард, он использует как _meta.fields, так и _meta.many_to_many. Глядя на django.forms.models.fields_for_model, это то, как вы могли бы сделать это:

opts = model._meta 
for f in sorted(opts.fields + opts.many_to_many): 
    print '%s: %s' % (f.name, f) 
4

модельные поля, содержащиеся на _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 

(См This example usage в django.forms.models.fields_for_model.)

+2

Возможно, вы захотите сопровождать свой код с помощью краткое описание того, что он делает. –

+2

----- done .----- – jxqz

58

Я знаю, что этот пост довольно старый, но я просто заботился сказать всем, кто ищет то же самое, что есть общественный и официальный API, чтобы сделать это: get_fields() и get_field()

Использование:

fields = model._meta.get_fields() 
my_field = model._meta.get_field('my_field') 

https://docs.djangoproject.com/en/1.8/ref/models/meta/

+6

Это на самом деле правильный ответ для более новой версии django. – chhantyal

+0

1.10 'get_fields()' https://docs.djangoproject.com/en/1.10/ref/models/meta/#django.db.models.options.Options.get_fields – Risadinha

1

Как об этом.

fields = Model._meta.fields 
+1

Я предполагаю, что можно получить доступ к свойствам поле. Кроме того, как указано в предыдущих ответах, есть 'many_to_many' и' virtual_fields'. – Jocke

+0

@ Jocke, вы правы. Может возникнуть необходимость в доступе к другому атрибуту.Ответ отредактирован. – JDE876

2

В настоящее время существует специальный метод - get_fields()

>>> from django.contrib.auth.models import User 
    >>> User._meta.get_fields() 

Он принимает два параметра, которые могут быть использованы для управления тем, какие поля возвращаются:

  • include_parents

    Истина по умолчанию. Рекурсивно включает в себя поля, определенные в родительских классах. Если установлено значение False, get_fields() будет искать только поля, объявленные непосредственно в текущей модели. Поля от моделей, которые непосредственно наследуются от абстрактных моделей или прокси-классов, считаются локальными, а не родителями.

  • include_hidden

    Ложный по умолчанию. Если установлено значение «Истина», get_fields() будет включать поля, которые используются для поддержки других функций поля. Это также будет включать в себя любые поля, которые имеют related_name (например, ManyToManyField или ForeignKey), которые начинаются с «+»

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