在django中查找模型字段的类型

时间:2012-01-30 14:53:09

标签: python django

我有一个这样的模型:

class Profile(models.Model):
    user = models.OneToOneField("User", verbose_name=u"user", null=True, blank=True, default=None)
    monthly_income = models.ForeignKey(MonthlyIncome, verbose_name=u"Monthly Income", null=True, blank=True, default=None)
    car = models.ManyToManyField(Car, verbose_name=u"Car?", null=True, blank=True, default=None)

如果用户更改了他的个人资料,这些更改将保存到另一个表(UpdateLog)。在视图中,我从UpdateLog进行查询,如果项目在Updatelog中,则选择框将被禁用。由于禁用的选择框不会向服务器发送任何数据,因此我将request.POST.copy()的禁用字段值添加为以下视图:

在视图中:

if request.method == "POST":
    post_values = request.POST.copy()
    query = UpdateLog.objects.filter(user=request.user.id)
    for a in query:
        field = a.filed_name
        try:
            sd = eval("profile.%s.id"%field) 
            post_values.update({field: u"%s"%sd})
        except AttributeError:
            print field

问题是:sd = eval("profile.%s.id"%field)仅适用于ForeignKey数据。我必须将sd与foreignkey和manytomany字段分开。如何识别模型中的字段类型?

2 个答案:

答案 0 :(得分:3)

考虑查看Django的模型选项(例如,Meta类)以获得更通用的解决方案。

from django.db import models

model_fields = dict((f.name, f) for f in MyModel._meta.fields)
test_field = field_dict[field_name]
if isinstance(test_field, models.OneToOneField):
    #it's a one to one field!
elif isinstance(test_field, models.ManyToManyField):
    #it's a one to one field!
elif isinstance(test_field, models.IntegerField):
    #it's an integer field!
#...

除了一般性之外,这种方法的一个好处是它不需要任何数据库访问 - 它只是检查模型定义指定的模式。

答案 1 :(得分:2)

我认为你正在寻找这样的东西:

from django.db import models
field_name = a.field_name
field = getattr(profile, field_name)
if isinstance(field, models.Model):
    # It's a model object
    # (accessing a foreign key returns a model object)
elif isinstance(field, models.manager.Manager):
    # It's a manager object
    # (accessing a many to many field returns a ManyRelatedManager)
else:
    raise ValueError("Unexpected field type")