具有外键和主键的用户模型?

时间:2017-12-19 16:06:06

标签: django django-models

我有一个自定义用户模型,设置为

class User(AbstractBaseUser, PermissionsMixin):

field1 = models.CharField(max_length=11, unique = True, primary_key = True)
field2 = models.CharField(max_length=5)

USERNAME_FIELD = 'field1'

    class Meta:
        app_label = 'accounts'
        db_table = "user"

我有几个与主键字段1相关的其他模型,这种关系效果很好。

我的问题是添加一个现有的数据库表,其主键是我的用户模型中的field2。

class ModelWantingToRelateOnField2(models.Model):
    field2 = models.OneToOneField(settings.AUTH_USER_MODEL, db_column='field2',primary_key=True, serialize=False, 
    max_length=5)

    class Meta:
        managed = False
        db_table = 'Table2'

当我添加一对一时,我的vizgraph数据模型显示它试图关联field1,当我需要在此模型上为field2发生关系而我的所有其他关系都在field1上。

我尝试过使用ForeignKey和related_name,但在迁移后,模型会尝试在field1上进行关联。

尝试在我的User模型之前加载table2时,我收到以下SQL错误:

django.db.utils.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]There are no primary
 or candidate keys in the referenced table 'Table2' that match the referencing column list in the foreign ke
y 'user_field2_id_8e77ca93_fk_Table2_Field2'. (1776) (SQLExecDirectW)")

首先使用ModelWantingToRelateOnField2 / FacilityDimension翻转的模型:

class FacilityDimension(models.Model):
    unit_num = models.CharField(db_column='Unit_Num', max_length=5, blank=True, null=True)  # Field name made lowercase.
    company_code = models.CharField(db_column='Company_Code', max_length=1, blank=True, null=True)  # Field name made lowercase.
    coid = models.CharField(db_column='Coid',primary_key=True, serialize=False, max_length=5, unique = True)  # Field name made lowercase.
    coid_name = models.CharField(db_column='COID_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    c_level = models.CharField(db_column='C_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    company_name = models.CharField(db_column='Company_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    s_level = models.CharField(db_column='S_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    sector_name = models.CharField(db_column='Sector_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    b_level = models.CharField(db_column='B_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    group_name = models.CharField(db_column='Group_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    r_level = models.CharField(db_column='R_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    division_name = models.CharField(db_column='Division_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    d_level = models.CharField(db_column='D_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    market_name = models.CharField(db_column='Market_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    f_level = models.CharField(db_column='F_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    cons_facility_name = models.CharField(db_column='Cons_Facility_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    lob_code = models.CharField(db_column='LOB_Code', max_length=3, blank=True, null=True)  # Field name made lowercase.
    lob_name = models.CharField(db_column='LOB_Name', max_length=20, blank=True, null=True)  # Field name made lowercase.
    sub_lob_code = models.CharField(db_column='Sub_LOB_Code', max_length=3, blank=True, null=True)  # Field name made lowercase.
    sub_lob_name = models.CharField(db_column='Sub_LOB_Name', max_length=20, blank=True, null=True)  # Field name made lowercase.
    state_code = models.CharField(db_column='State_Code', max_length=2, blank=True, null=True)  # Field name made lowercase.
    pas_id_current = models.CharField(db_column='PAS_ID_Current', max_length=8, blank=True, null=True)  # Field name made lowercase.
    pas_current_name = models.CharField(db_column='PAS_Current_Name', max_length=40, blank=True, null=True)  # Field name made lowercase.
    pas_id_future = models.CharField(db_column='PAS_ID_Future', max_length=8, blank=True, null=True)  # Field name made lowercase.
    pas_future_name = models.CharField(db_column='PAS_Future_Name', max_length=40, blank=True, null=True)  # Field name made lowercase.
    summary_7_member_ind = models.CharField(db_column='Summary_7_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_8_member_ind = models.CharField(db_column='Summary_8_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_phys_svc_member_ind = models.CharField(db_column='Summary_Phys_Svc_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_asd_member_ind = models.CharField(db_column='Summary_ASD_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_imaging_member_ind = models.CharField(db_column='Summary_Imaging_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_oncology_member_ind = models.CharField(db_column='Summary_Oncology_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_cath_lab_member_ind = models.CharField(db_column='Summary_Cath_Lab_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_intl_member_ind = models.CharField(db_column='Summary_Intl_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    summary_other_member_ind = models.CharField(db_column='Summary_Other_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    pas_coid = models.CharField(db_column='PAS_COID', max_length=5, blank=True, null=True)  # Field name made lowercase.
    pas_status = models.CharField(db_column='PAS_Status', max_length=1, blank=True, null=True)  # Field name made lowercase.
    company_code_operations = models.CharField(db_column='Company_Code_Operations', max_length=3, blank=True, null=True)  # Field name made lowercase.
    osg_pas_ind = models.CharField(db_column='OSG_PAS_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    abs_facility_member_ind = models.CharField(db_column='ABS_Facility_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    abl_facility_member_ind = models.CharField(db_column='ABL_Facility_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    intl_pmis_member_ind = models.CharField(db_column='INTL_PMIS_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    hsc_member_ind = models.CharField(db_column='HSC_Member_Ind', max_length=1, blank=True, null=True)  # Field name made lowercase.
    loaddate = models.DateTimeField(db_column='LoadDate', blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'Facility_Dimension'


class User(AbstractBaseUser, PermissionsMixin):



    email = models.EmailField(unique=True)
    username = models.CharField(max_length=7, unique=True)
    formattedusername = models.CharField(max_length=11, unique=True, primary_key = True)
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=140)
    date_joined = models.DateTimeField(default=timezone.now)
    is_active = models.BooleanField(default=True)
    is_staff = models.BooleanField(default=False)
    is_cfo = models.BooleanField(default=False)
    facility = models.CharField(max_length=140)
    officename = models.CharField(max_length=100)
    jobdescription = models.CharField(max_length=140)
    positioncode = models.CharField(max_length = 100)
    positiondescription = models.CharField(max_length=140)
    coid = models.ForeignKey(FacilityDimension, max_length=5)
    streetaddress = models.CharField(max_length=140)
    title = models.CharField(max_length=100)



    USERNAME_FIELD = 'username'

    class Meta:
        app_label = 'accounts'
        db_table = "user"

    def save(self, *args, **kwargs):
        self.formattedusername = '{domain}\{username}'.format(
            domain='HCA', username=self.username)
        super(User, self).save(*args, **kwargs);

    def get_short_name(self):
        return self.username

#    REQUIRED_FIELDS = "username"

    def __str__(self):
        return '%s - %s %s' % (self.username, self.first_name, self.last_name)


class QvDatareducecfo(models.Model):
    cfo_fname = models.CharField(db_column='CFO_FName', max_length=100, blank=True, null=True)  # Field name made lowercase.
    cfo_lname = models.CharField(db_column='CFO_LName', max_length=100, blank=True, null=True)  # Field name made lowercase.
    cfo_ntname = models.OneToOneField(settings.AUTH_USER_MODEL,db_column='CFO_NTName',max_length=11, primary_key=True)  # Field name made lowercase.
    cfo_type = models.IntegerField(db_column='CFO_Type', blank=True, null=True)  # Field name made lowercase.
    org_level_id = models.IntegerField(db_column='Org_Level_ID', blank=True, null=True)  # Field name made lowercase.
    org_level = models.CharField(db_column='Org_Level', max_length=255, blank=True, null=True)  # Field name made lowercase.
    unit_no = models.CharField(db_column='Unit_No', max_length=10, blank=True, null=True)  # Field name made lowercase.
    dr_code = models.CharField(db_column='DR_Code', max_length=255, blank=True, null=True)  # Field name made lowercase.
    dr_name = models.CharField(db_column='DR_Name', max_length=255, blank=True, null=True)  # Field name made lowercase.
    cfo_dr_code = models.CharField(db_column='CFO_DR_Code', max_length=255, blank=True, null=True)  # Field name made lowercase.
    cfo_dr_name = models.CharField(db_column='CFO_DR_Name', max_length=255, blank=True, null=True)  # Field name made lowercase.
    b_level = models.CharField(db_column='B_Level', max_length=6, blank=True, null=True)  # Field name made lowercase.
    group_name = models.CharField(db_column='Group_Name', max_length=255, blank=True, null=True)  # Field name made lowercase.
    load_date = models.DateTimeField(db_column='Load_Date', blank=True, null=True)  # Field name made lowercase.
    beg_date = models.DateTimeField(db_column='Beg_Date', blank=True, null=True)  # Field name made lowercase.
    end_date = models.DateTimeField(db_column='End_Date', blank=True, null=True)  # Field name made lowercase.
    active = models.IntegerField(db_column='Active', blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'QV_DataReduceCFO'

    def __str__(self):
        return str(self.cfo_ntname)





class QvReportList(models.Model):
    qv_dept_id = models.CharField(db_column='QV_Dept_ID', max_length=100)  # Field name made lowercase.
    report_id = models.CharField(db_column='Report_ID',primary_key=True, max_length=100, serialize=False)  # Field name made lowercase.
    report_name = models.CharField(db_column='Report_Name', max_length=255, blank=True, null=True)  # Field name made lowercase.
    report_name_sc = models.CharField(db_column='Report_Name_SC', max_length=255, blank=True, null=True)  # Field name made lowercase.
    qv_filename = models.CharField(db_column='QV_FileName', max_length=255, blank=True, null=True)  # Field name made lowercase.
    report_access = models.CharField(db_column='Report_Access', max_length=20, blank=True, null=True)  # Field name made lowercase.
    report_group_id = models.IntegerField(db_column='Report_Group_ID', blank=True, null=True)  # Field name made lowercase.
    report_sub_group_id = models.IntegerField(db_column='Report_Sub_Group_ID', blank=True, null=True)  # Field name made lowercase.
    load_date = models.DateTimeField(db_column='Load_Date', blank=True, null=True)  # Field name made lowercase.
    approver_fname = models.CharField(db_column='Approver_FName', max_length=255, blank=True, null=True)  # Field name made lowercase.
    approver_lname = models.CharField(db_column='Approver_LName', max_length=255, blank=True, null=True)  # Field name made lowercase.
    approver_ntname = models.CharField(db_column='Approver_NTName', max_length=255, blank=True, null=True)  # Field name made lowercase.
    beg_date = models.DateTimeField(db_column='Beg_Date', blank=True, null=True)  # Field name made lowercase.
    end_date = models.DateTimeField(db_column='End_Date', blank=True, null=True)  # Field name made lowercase.
    active = models.IntegerField(db_column='Active', blank=True, null=True)  # Field name made lowercase.
    approval_id = models.IntegerField(db_column='Approval_ID', blank=True, null=True)  # Field name made lowercase.
    role_based_id = models.IntegerField(db_column='Role_Based_ID', blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'QV_Report_List'


class QVReportAccess(models.Model):
    user_status = models.CharField(db_column='User_Status', max_length = 20)  # Field name made lowercase.
    ntname = models.OneToOneField(settings.AUTH_USER_MODEL,db_column='NTName', max_length=11,primary_key=True, serialize=False)  # Field name made lowercase.
    report_name = models.CharField(db_column='Report_Name', max_length=50, blank=True, null=True)  # Field name made lowercase.
    report_name_sc = models.CharField(db_column='Report_Name_SC', max_length=30, blank=True, null=True)  # Field name made lowercase.
    datareduce_report_code = models.IntegerField(db_column='DataReduce_Report_Code', blank=True, null=True)  # Field name made lowercase.
    role_based_id = models.IntegerField(db_column='Role_Based_ID', blank=True, null=True)  # Field name made lowercase.
    report_id = models.OneToOneField(QvReportList,db_column='Report_ID', max_length=100, blank=True, null=True)  # Field name made lowercase.
    report_group_id = models.IntegerField(db_column='Report_Group_ID', blank=True, null=True)  # Field name made lowercase.
    report_access = models.CharField(db_column='Report_Access', max_length=50, blank=True, null=True)  # Field name made lowercase.
    sr_datareduce_summary_code = models.CharField(db_column='SR_DataReduce_Summary_Code', max_length=10, blank=True, null=True)  # Field name made lowercase.
    sr_datareduce_patient_code = models.CharField(db_column='SR_DataReduce_Patient_Code', max_length=10, blank=True, null=True)  # Field name made lowercase.
    userid = models.IntegerField(db_column='UserID', blank=True, null=True)  # Field name made lowercase.
    user_group_id = models.IntegerField(db_column='User_Group_ID', blank=True, null=True)
    access_level_id = models.IntegerField(db_column='Access_Level_ID', blank=True, null=True)
    active = models.IntegerField(db_column='Active', blank=True, null=True)
    qv_statusid = models.IntegerField(db_column='QV_StatusID', blank=True, null=True)
    employee_status_id = models.IntegerField(db_column='Employee_Status_ID', blank = True, null = True)
    new_user = models.IntegerField(db_column='New_User', blank = True, null = True)
    new_access = models.IntegerField(db_column='New_Access', blank = True, null = True)
    new_report = models.IntegerField(db_column='New_Report', blank = True, null = True)
    changed_row = models.IntegerField(db_column='Changed_Row',blank = True, null = True)
    last_change_date = models.DateTimeField(db_column='Last_Change_Date', blank=True, null=True)  # Field name made lowercase.
    access_beg_date = models.DateTimeField(db_column='Access_Beg_Date', blank=True, null=True)  # Field name made lowercase.
    access_end_date = models.DateTimeField(db_column='Access_End_Date', blank=True, null=True)  # Field name made lowercase.
    report_beg_date = models.DateTimeField(db_column='Report_Beg_Date', blank=True, null=True)  # Field name made lowercase.
    report_end_date = models.DateTimeField(db_column='Report_End_Date', blank=True, null=True)  # Field name made lowercase.
    qv_startdate = models.DateTimeField(db_column='QV_StartDate', blank=True, null=True)  # Field name made lowercase.
    load_date = models.DateTimeField(db_column='Load_Date', blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = False
        db_table = 'QV_ReportAccess'

class QVFormAccessRequest(models.Model):
    ntname = models.CharField(max_length=11)
    first_name = models.CharField(max_length=40)
    last_name = models.CharField(max_length=140)
    coid = models.CharField(max_length=5)
    datareducecode = models.CharField(max_length=2500)
    facility = models.CharField(max_length=140)
    title = models.CharField(max_length=100)
    report_id = models.CharField(max_length=100)
    accesslevel_id = models.CharField(max_length=100)
    phi = models.BooleanField(default=False)
    access_beg_date = models.DateTimeField(blank=True, null=True)  # Field name made lowercase.
    access_end_date = models.DateTimeField(blank=True, null=True)  # Field name made lowercase.

    class Meta:
        managed = True
        db_table = 'QV_FormAccessRequest'





class DjangoMigrations(models.Model):
    app = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    applied = models.DateTimeField()

    class Meta:
        managed = False
        db_table = 'django_migrations'

class Sysdiagrams(models.Model):
    name = models.CharField(max_length=128)
    principal_id = models.IntegerField()
    diagram_id = models.AutoField(primary_key=True)
    version = models.IntegerField(blank=True, null=True)
    definition = models.BinaryField(blank=True, null=True)

    class Meta:
        managed = False
        db_table = 'sysdiagrams'
        unique_together = (('principal_id', 'name'),)

删除所有django表后,这是我的移民:

WARNINGS:
accounts.User.coid: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
        HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
Migrations for 'accounts':
  accounts\migrations\0001_initial.py
    - Create model DjangoMigrations
    - Create model FacilityDimension
    - Create model QvDatareducecfo
    - Create model QVReportAccess
    - Create model QvReportList
    - Create model Sysdiagrams
PS C:\python\security> python manage.py makemigrations
System check identified some issues:

WARNINGS:
accounts.User.coid: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
        HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
Migrations for 'accounts':
  accounts\migrations\0002_qvformaccessrequest_user.py
    - Create model User
    - Create model QVFormAccessRequest

以下是运行migrate时的错误消息:

System check identified some issues:

WARNINGS:
accounts.User.coid: (fields.W342) Setting unique=True on a ForeignKey has the same effect as using a OneToOneField.
        HINT: ForeignKey(unique=True) is usually better served by a OneToOneField.
Operations to perform:
  Apply all migrations: accounts, admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0001_initial... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying accounts.0001_initial... OK
  Applying accounts.0002_qvformaccessrequest_user...Traceback (most recent call last):
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\sql_server\pyodbc\base.py", line 545, in execute
    return self.cursor.execute(sql, params)
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]There are no primary or candidate keys in the referenced table 'F
acility_Dimension' that match the referencing column list in the foreign key 'user_coid_id_8e77ca93_fk_Facility_Dimension_Coid'. (1776) (SQLExecDirectW)")

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "manage.py", line 22, in <module>
    execute_from_command_line(sys.argv)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 364, in execute_from_command_lin
e
    utility.execute()
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\__init__.py", line 356, in execute
    self.fetch_command(subcommand).run_from_argv(self.argv)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 283, in run_from_argv
    self.execute(*args, **cmd_options)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\base.py", line 330, in execute
    output = self.handle(*args, **options)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\core\management\commands\migrate.py", line 204, in handle
    fake_initial=fake_initial,
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 115, in migrate
    state = self._migrate_all_forwards(state, plan, full_plan, fake=fake, fake_initial=fake_initial)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 145, in _migrate_all_forwards
    state = self.apply_migration(state, migration, fake=fake, fake_initial=fake_initial)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\migrations\executor.py", line 244, in apply_migration
    state = migration.apply(state, schema_editor)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\base\schema.py", line 93, in __exit__
    self.execute(sql)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\sql_server\pyodbc\schema.py", line 604, in execute
    cursor.execute(sql, params)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\utils\six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\django\db\backends\utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "C:\Users\HFA9592\AppData\Local\Programs\Python\Python36\lib\site-packages\sql_server\pyodbc\base.py", line 545, in execute
    return self.cursor.execute(sql, params)
django.db.utils.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC SQL Server Driver][SQL Server]There are no primary or candidate keys in the referenced
 table 'Facility_Dimension' that match the referencing column list in the foreign key 'user_coid_id_8e77ca93_fk_Facility_Dimension_Coid'. (1776) (SQLExecDir
ectW)")

1 个答案:

答案 0 :(得分:1)

听起来多个用户可以拥有相同的FacilityDimension。因此,您应该在User模型上拥有外键,而不是FacilityDimension

class User(AbstractBaseUser, PermissionsMixin):
    coid = models.ForeignKey('FacilityDimension', db_constraint=False)

如果目标模型上不存在主键/唯一索引,Django将无法创建外键约束。您可以通过设置db_constraint来阻止Django创建约束。

如果您使用字符串'FacilityDimension'而不是类FacilityDimension,则不必重新订购模型。

您不需要设置to_field,因为外键指向FacilityDimension.coid的{​​{1}}字段。