python - Django:用“_code”或其他后缀替换外键属性名(以及列名)“_id”后缀
问题描述
我的问题与这个问题密切相关,但又略有不同。
给定以下 Django 模型:
class Country(models.Model):
code = models.CharField(primary_key=True)
class Person(models.Model):
country = models.ForeignKey(Country, on_delete=models.CASCADE)
请注意,我在Country
called上指定了一个自定义主键字段code
。该类Country
不应有id
字段或属性。这工作正常。
当然,我希望Person
班级的外键Country
能够使用该code
字段。这也很好。到目前为止,一切都很好。
但是,我也真的希望表中的基础列名Person
完全是country_code
. 不是 country_id
。所以我添加了db_column
字段参数:
class Person(models.Model):
country = models.ForeignKey(
Country,
on_delete=models.CASCADE,
db_column='country_code',
)
现在列名已正确命名country_code
,而不是country_id
. 到目前为止,一切都很好。
现在。在我的 python 代码中,我希望能够通过一个人以正常方式访问一个国家:
person = Person.objects.get(...)
country = person.country
但是,我希望能够通过使用country_code
, not country_id
的人访问国家代码 pk ,如下所示:
person = Person.objects.get(...)
country_code = person.country_code
而且我还希望能够使用参数创建Person 对象country_code
,而不是country_id
:
person = Person(country_code='foo')
而且我还希望能够使用参数查询Person 对象country_code
,而不是country_id
:
people = Person.objects.filter(country_code='foo')
不应有属性 person.country_id
、字段或列。只有person.country
和person.country_code
。是的,我希望准确调用该字段/属性/列person.country_code
,即使 person.country_id
它具有相同的值也不行。这就是我在 Python 和 RDBMS 中想要的确切名称。
到目前为止,我还没有能够做到这一点。我尝试过将to_field
参数添加到Person.country
字段声明中,如下所示:
class Person(models.Model):
country = models.ForeignKey(
Country,
on_delete=models.CASCADE,
to_field='code',
db_column='country_code',
)
这似乎没有达到预期的效果。
是否可以在 Django 中更改模型的外键字段属性名称(以及基础列名称)?
在我看来,这似乎不是一件奇怪的事情。也许我错了。这可能吗?这是否太难/不标准而不值得?我是在自找麻烦吗?
解决方案
自定义外键子类
class NamedForeignKey(models.ForeignKey):
suffix_idname = 'id'
def __init__(self, *args, **kwargs):
suffix_idname = kwargs.pop('suffix_idname', None)
if suffix_idname:
self.suffix_idname = suffix_idname
super().__init__(*args, **kwargs)
def get_attname(self):
return '%s_%s' % (self.name, self.suffix_idname)
class Person(models.Model):
country = NamedForeignKey(
Country,
on_delete=models.CASCADE,
suffix_idname='code',
)
推荐阅读
- r - 根据条件查找列中最近出现的时间戳
- intellij-idea - 如何将代码样式从 WebStorm 导入 Visual Studio Code?
- python - Pandas 如何根据所有行的值、应用于整个数据框的特定列值向数据框添加新列
- python - 如何根据用户对下拉列表的响应定义使用哪个文件?
- reactjs - 我应该在哪里调用 setintreval 反应
- c# - PostAsync 语句导致测试完成不确定
- java - Hibernate Criteria - 投影中的多种实体类型
- c# - Azure Web 应用程序和 Azure VM 上的 Windows 窗体应用程序之间的通信
- python - 这是 Python 中通常使用的/一种好的做法吗?
- python - 为什么站点匹配查询不存在?