如何在Django中实现多值属性? [英] How to implement multivalued attribute in Django?

查看:150
本文介绍了如何在Django中实现多值属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个具有以下表格的旧数据库:

I have a legacy database with the following tables:

person_id (PK)  |  first_name  |  last_name
        1       |  John        |  Doe
        2       |  David       |  Bentley

电话号码

person_id (FK,PK) |  phone_number (PK)  | area_code (PK)
        1         |  758-4551           | 909
        1         |  763-3445           | 909
        2         |  634-0011           | 637

每个人都可以拥有零个或多个电话号码,这是该人实体的多值属性。

Every person can have zero or more phone numbers, which is a multivalued attribute of the person entity.

我尝试使用Django的inspectdb命令生成了以下model.py:

I've tried using the Django's inspectdb command which generated the following models.py:

class Person(models.Model):
    person_id = models.BigIntegerField(primary_key=True)
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    class Meta:
        managed = False
        db_table = 'person'


class PhoneNumbers(models.Model):
    person = models.ForeignKey(Person, models.DO_NOTHING)
    phone_number = models.CharField(max_length=15)
    area_code = models.CharField(max_length=15)

    class Meta:
        managed = False
        db_table = 'phonenumbers'
        unique_together = (('person', 'phone_number', 'area_code'),)

但是,当我尝试保存PhoneNumbers的新实例时,Django返回了以下错误消息:

However, when I tried to save a new instance of PhoneNumbers, Django returned the following error message:

django.db.utils.ProgrammingError: column phonenumbers.id does not exist

显然Django希望电话号码的表具有代理键。
由于电话号码表不是实体,因此在我的旧数据库中没有代理键。请注意,电话号码的表主键是其所有列的组成。

Apparently Django expects the phone number's table to have a surrogate key. Since the phone number's table is not an entity, it doesn't have a surrogate key in my legacy database. Notice that the phonenumbers' table primary key is a composition of all of its columns.

如何将这些表映射到Django的模型中,以便其与我的旧数据库一起工作?

How can I map these tables into Django's models so that it works with my legacy database?

推荐答案

Django不支持复合主键,并且PhoneNumbers表的主键跨越三列。此门票已开放多年。有一个第三方插件,它提供了复合主键支持,但是已经两年没有维护,并且不兼容。使用最新版本的Django。

Django does not support composite primary keys and your PhoneNumbers table has a primary key that spans three columns. This ticket has been open for years. There is a third party plugin that provide composite primary key support but it's been unmaintained for two years and incompatible with the latest versions of Django.

解决方案是添加主键。

The solution is to add the primary key. But before that do

./manage.py migrate

这将确保django所需的表已在旧数据库中创建。

This will make sure that the tables needed by django are created in your legacy database.

现在将模型修改为删除此行

Now modify your models to delete this line

managed = False

这向django发出信号,表示对模型的更改将反映在数据库中。然后按如下所示更改模型。

This signals django that alterations to the models are to be reflected in the database. Then change your model as follows.

class Person(models.Model):
    id = models.BigIntegerField(primary_key=True, db_column='person_id')
    first_name = models.CharField(max_length=255)
    last_name = models.CharField(max_length=255)

    class Meta:
        db_table = 'person'


class PhoneNumbers(models.Model):
    id = models.BigIntegerField(primary_key=True)
    person = models.ForeignKey(Person, models.DO_NOTHING)
    phone_number = models.CharField(max_length=15)
    area_code = models.CharField(max_length=15)

    class Meta:
        db_table = 'phonenumbers'
        unique_together = (('person', 'phone_number', 'area_code'),)

然后

 ./manage.py makemigrations  your_app_name
 ./manage.py migrate

注意,我已经重命名了Person中的主键字段。这只是表面上的变化。这是因为约定是将主键字段作为id。当您处理许多模型时,您可能会忘记该模型的主键命名不同。因此发生了变化。

Notice that I have renamed the primary key field in Person. This is just a cosmetic change. That's because the convention is to have the primary key field as id. When you are dealing with lots of models you are likely to forget that this model's primary key was named differently. Hence the change.

这篇关于如何在Django中实现多值属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆