修改django的默认" _id"相关对象的后缀

时间:2014-02-03 10:28:06

标签: python django

我正在将django与遗留系统和数据库集成,并且有一个看起来像这样的模型

class Label(models.Model)
    iLabelID = models.IntegerField(db_column='LABELID', primary_key=True)
    organization = models.OneToOneField(Organization, related_name='labels', db_column='ORGANIZATION')
    sLabelText = models.CharField(max_length=42)

使用这种表示法(或多或少hungarian notation)是项目的要求。

以下内容适用于django:

>>> Label.objects.get(organization_id=1)

但我希望能够写下这个:

>>> Label.objects.get(iOrganizationID=1)

我尝试使用

继承models.OneToOneField
class MyOneToOneField(models.OneToOneField):
    def get_attname(self):
        # default is:
        # return '%s_id' % self.name
        return 'i%s%sID' % (self.name[0].upper(), self.name[1:])

但这是我在尝试使用它时遇到的错误:

>>> Label.objects.get(iOrganizationID=1)
Traceback (most recent call last):
  File "<console>", line 1, in <module>
  File "django/db/models/manager.py", line 151, in get
    return self.get_queryset().get(*args, **kwargs)
  File "django/db/models/query.py", line 301, in get
    num = len(clone)
  File "django/db/models/query.py", line 77, in __len__
    self._fetch_all()
  File "django/db/models/query.py", line 854, in _fetch_all
    self._result_cache = list(self.iterator())
  File "django/db/models/query.py", line 230, in iterator
    obj = model(*row_data)
  File "django/db/models/base.py", line 347, in __init__
    setattr(self, field.attname, val)
AttributeError: can't set attribute

编辑:这是另一个痛点:

我希望生成一些JSON。这个JSON将被送到我无法控制的系统的另一部分(不可能更改名称)。我希望我能做到以下几点:

json.dumps(list(Label.objects.values('iLabelID', 'iOrganizationID', 'sAnotherValue')))

但这是不可能的。我必须这样做

list(Label.objects.values('iLabelID', 'organization_id', 'sAnotherValue'))

然后手动将organization_id映射到iOrganizationID,尽管这不是标签ID的问题。它使代码更难以维护,读取和执行更慢。

请注意,这是特定于匈牙利表示法,您可能需要使用_identifier_pk或其他代替_id的后缀。

EDIT2:我必须犯了另一个错误,因为当lanzz指出get_attname确实有效-_-

1 个答案:

答案 0 :(得分:0)

我使用您的代码的一些修改解决了它:

class CustomAttrNameForeignKey(djangoFields.related.ForeignKey):
    def __init__(self, *args, **kwargs):
        attname = kwargs.pop('attrname', None)
        super(CustomAttrNameForeignKey, self).__init__(*args, **kwargs)
        self.attname = attname or super(CustomAttrNameForeignKey, self).get_attname()

    def get_attname(self):
        return self.attname

class AModelUsingThis(djangoModels.Model):
    snapshot = CustomAttrNameForeignKey(
            ParentalModel, db_column="timestamp", to_field="timestamp",
            attrname='timestamp', related_name="children")

在这种情况下,我们在模型中获得FK的一个属性,根本没有后缀,但是给出了名称。我还没有在DB上测试它,但只是尝试使用这个自定义FK实例化模型 - 它工作正常。