开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜