Given a QS field lookup key, how to find fields type across joins?
For a little background: I am trying to build a robust dynamic queryset form to allow semi-power users (marketers?) deep access to analytics data.
I've already built a function to provide field lookup keys, for 开发者_C百科example, given a Model like:
class Profile(models.Model):
user = models.OneToOneField("auth.User")
age = models.PositiveIntegerField()
I have a recursive function that returns:
[
'id',
'user',
'user__id',
'user__username',
'user__first_name',
#...snip...
'user__is_active',
'user__date_joined',
#...snip...
'user__groups__permissions',
'user__groups__permissions__id',
'user__groups__permissions__name',
#...snip...
'age',
]
What I'd like to happen is, after a user selects their chosen key, display & interpret the appropriate standard form field (widget) akin to what a ModelForm would do, but I need that field's type first.
So how would I go about feeding a function anything like 'age', 'user__date_joined' and 'user_groups_permissions__name' and get back PositiveIntegerField, DateField, and CharField (respectively?).
I'm assuming Django has to do this in the ORM, so I am sure the functionality is baked into Django somewhere, I just haven't found it.
The info you want is in the class's meta attribute:
Profile._meta.get_field_by_name('field_name')
This returns:
(field_object, model, direct, m2m)
The model
is filled in if you got this from a model object, rather than directly from the class object, direct
is true if the field exists on the model (rather than generated as a result of the ORM's lookup), and m2m
is, well, if this field is part of a many-to-many relationship.
[EDIT For '__' relationships]
In the Django source code (db/models/sql/query.py), they disassemble the field type with the following code. I can't speak to it, but it looks semantically correct:
parts = field_name.split('__')
cur_model = model
for name in parts:
(field, _, _, _) = cur_model._meta.get_field_by_name(name)
cur_model = field.rel.to
This basically says that for foreign key relationships the field only contains the ID, and the rel.to
is what Django uses to actually get the model that the field refers to, and this loop descends through the list of fields until it finds the last one in your string.
精彩评论