Django - 从其init函数中获取字段的名称

时间:2012-02-09 21:45:08

标签: django django-models

请考虑以下代码:

class MyManyToManyField(models.ManyToManyField):
  def __init__(self,*args,**kwargs):
    field_name = ?!?
    kwargs["related_name"] = "%(app_label)s.%(class)s." + field_name
    super(MetadataManyToManyField,self).__init__(*args,**kwargs)

class MyModelA(models.Model):
  modelAField = MyManyToManyField("MyModelB")

class MyModelB(models.Model):
  pass

我有没有办法从我重载的init函数中访问该字段的名称?我希望modelAField的related_name最终成为“MyAppName.MyModelA.modelAField”。

我想过把它作为一个小丑传递:

  modelAField = MyManyToManyField("MyModelB",related_name="modelAField")

然后在init中使用它:

  field_name = kwargs.pop("related_name",None)
  if not field_name:
    raise AttributeError("you have to supply a related name!")

但我希望有更好的东西。

感谢。

3 个答案:

答案 0 :(得分:2)

使用contribute_to_class

如前所述,在将字段对象分配给类中的变量之前,必须通过调用其__init__函数来实例化该字段对象。

然而,在构建模型时,Django在名为contribute_to_class的字段上查找方法。如果它存在,它将被调用如下:

new_field.object.contribute_to_class(ModelClass, field_name)

如果在自定义字段类中重写此方法,则可以在将字段添加到模型的位置执行所需的初始化。

答案 1 :(得分:1)

我不认为这是可能的。 MyManyToManyField对象在被分配给变量之前将被实例化,所以现在要做一些聪明的事情还为时过早。

对于与字段交互的模型,Django的元类中可能存在相同的魔法,有可能劫持这种交互并将逻辑放在那里。但我现在只是在猜测。

答案 2 :(得分:1)

作为一个kwarg传球似乎并不麻烦。

我怀疑Python无法决定实例的名称,因为一个对象可以有很多引用指针。

例如

x = YourClass()
y = x

YourClass'x'或'y'实例的名称是?或者它只是YourClass的一个实例?