Actually get_fields() returns fields in a fixed order.
Take a look into django example:
>>> from django.contrib.auth.models import User
>>> User._meta.get_fields()
(<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>)
I've repeated this code and got the same results.
If you will go deeper and look into the sources, you will find that the order is the following:
- Each
parent fields fetched in a recursive way.
- Remote fields.
- Local fields.
- Local many-to-many fields.
- Private fields.
All that says that if you define some trivial field before some other trivial field in your model, you will always get it in the same order in get_fields() results.
But be careful on relying on a non-documented behaviour, so it could be changed in a future without any warning.