204
_meta
is private, but itβs relatively stable. There are efforts to formalise it, document it and remove the underscore, which might happen before 1.3 or 1.4. I imagine effort will be made to ensure things are backwards compatible, because lots of people have been using it anyway.
If youβre particularly concerned about compatibility, write a function that takes a model and returns the fields. This means if something does change in the future, you only have to change one function.
def get_model_fields(model):
return model._meta.fields
I believe this will return a list of Field
objects. To get the value of each field from the instance, use getattr(instance, field.name)
.
Update: Django contributors are working on an API to replace the _Meta object as part of a Google Summer of Code. See:
β https://groups.google.com/forum/#!topic/django-developers/hD4roZq0wyk
β https://code.djangoproject.com/wiki/new_meta_api
154
I know this post is pretty old, but I just cared to tell anyone who is searching for the same thing that there is a public and official API to do this: get_fields()
and get_field()
Usage:
fields = model._meta.get_fields()
my_field = model._meta.get_field('my_field')
https://docs.djangoproject.com/en/3.2/ref/models/meta/#retrieving-all-field-instances-of-a-model
- [Django]-Change a Django form field to a hidden field
- [Django]-How to disable admin-style browsable interface of django-rest-framework?
- [Django]-Best way to integrate SqlAlchemy into a Django project
27
get_fields()
returns a tuple
and each element is a Model field
type, which canβt be used directly as a string. So, field.name
will return the field name
my_model_fields = [field.name for field in MyModel._meta.get_fields()]
The above code will return a list conatining all fields name
Example
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']
- [Django]-How to check Django version
- [Django]-Disabled field is not passed through β workaround needed
- [Django]-__init__() got an unexpected keyword argument 'mimetype'
16
Now there is special method β get_fields()
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
It accepts two parameters that can be used to control which fields are returned:
-
include_parents
True by default. Recursively includes fields defined on parent classes. If set to False, get_fields() will only search for fields declared directly on the current model. Fields from models that directly inherit from abstract models or proxy classes are considered to be local, not on the parent.
-
include_hidden
False by default. If set to True, get_fields() will include fields that are used to back other fieldβs functionality. This will also include any fields that have a related_name (such as ManyToManyField, or ForeignKey) that start with a β+β
- [Django]-Django, Models & Forms: replace "This field is required" message
- [Django]-Aggregate() vs annotate() in Django
- [Django]-How do I match the question mark character in a Django URL?
11
fields = [f"{f.name}_id" if f.is_relation else f.name for f in model._meta.fields]
- [Django]-How to select a record and update it, with a single queryset in Django?
- [Django]-Django model one foreign key to many tables
- [Django]-Delete multiple objects in django
10
This is something that is done by Django itself when building a form from a model. It is using the _meta attribute, but as Bernhard noted, it uses both _meta.fields and _meta.many_to_many. Looking at django.forms.models.fields_for_model, this is how you could do it:
opts = model._meta
for f in sorted(opts.fields + opts.many_to_many):
print '%s: %s' % (f.name, f)
- [Django]-How do I run tests against a Django data migration?
- [Django]-Table thumbnail_kvstore doesn't exist
- [Django]-How do I add a placeholder on a CharField in Django?
6
The model fields contained by _meta are listed in multiple locations as lists of the respective field objects. It may be easier to work with them as a dictionary where the keys are the field names.
In my opinion, this is most irredundant and expressive way to collect and organize the model field objects:
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
(See This example usage in django.forms.models.fields_for_model.)
- [Django]-Django testing: Test the initial value of a form field
- [Django]-Is there a way to filter a queryset in the django admin?
- [Django]-Django REST framework: non-model serializer
- [Django]-Best practices for adding .gitignore file for Python projects?
- [Django]-Error: could not determine PostgreSQL version from '10.3' β Django on Heroku
- [Django]-Django related_name for field clashes
2
If you need this for your admin site, there is also the ModelAdmin.get_fields
method (docs), which returns a list
of field name strings
.
For example:
class MyModelAdmin(admin.ModelAdmin):
# extending change_view, just as an example
def change_view(self, request, object_id=None, form_url='', extra_context=None):
# get the model field names
field_names = self.get_fields(request)
# use the field names
...
- [Django]-How do I make many-to-many field optional in Django?
- [Django]-Django's Double Underscore
- [Django]-Django β accessing the RequestContext from within a custom filter
2
As per the django documentation 2.2 you can use:
To get all fields: Model._meta.get_fields()
To get an individual field: Model._meta.get_field('field name')
ex. Session._meta.get_field('expire_date')
- [Django]-Django: Fat models and skinny controllers?
- [Django]-Django MEDIA_URL and MEDIA_ROOT
- [Django]-No module named MySQLdb
1
instance._meta.get_fields()
returns a list of all the fields (i.e. columns) in a Django model.
This method is used to introspect the modelβs fields, their types, and their relationships with other models. The method returns a list of Field objects, which represent the individual fields in the model.
For example, suppose you have a Django model called MyModel
. You can use instance._meta.get_fields()
to get a list of all the fields in the model:
from myapp.models import MyModel
my_instance = MyModel.objects.get(id=1)
fields = my_instance._meta.get_fields()
The fields variable will now contain a list of all the fields in the MyModel
model, including fields such as id
, name
, created_at
, and any related fields (such as foreign keys). You can use this list to access and manipulate the individual fields in the model.
- [Django]-How to monkey patch Django?
- [Django]-How do I reuse HTML snippets in a django view
- [Django]-Get the list of checkbox post in django views
0
Another way is add functions to the model and when you want to override the date you can call the function.
class MyModel(models.Model):
name = models.CharField(max_length=256)
created = models.DateTimeField(auto_now_add=True)
modified = models.DateTimeField(auto_now=True)
def set_created_date(self, created_date):
field = self._meta.get_field('created')
field.auto_now_add = False
self.created = created_date
def set_modified_date(self, modified_date):
field = self._meta.get_field('modified')
field.auto_now = False
self.modified = modified_date
my_model = MyModel(name='test')
my_model.set_modified_date(new_date)
my_model.set_created_date(new_date)
my_model.save()
- [Django]-Django error when installing Graphite β settings.DATABASES is improperly configured. Please supply the ENGINE value
- [Django]-How do I use pagination with Django class based generic ListViews?
- [Django]-How do I make many-to-many field optional in Django?