Django 3 主键问题
Django 3 primary key issues
我的 Django 模型有问题,主要是主键问题。
我使用管理界面来管理我的数据。我已经建立了一个由 3 个主键组成的数据库,以减少多个条目 (year
、month
、bnr
)。
但是我的模型中没有涵盖这一点,因为 django 只接受一个主键。我尝试了一些东西,但 none 对我有帮助。管理界面总是给我一个错误。
- 删除模型中的所有主键
- 试图在我的 model/Database 中添加 ID 列,但未在我的数据库中声明为主键
- 添加了
unique_together
现在我的模型是这样的:
class BalBalance(models.Model):
month = models.PositiveIntegerField(default=datetime.datetime.now().month, validators=[MinValueValidator(1), MaxValueValidator(12)])
year = models.PositiveIntegerField(default=datetime.datetime.now().year, validators=[MinValueValidator(1990), MaxValueValidator(datetime.datetime.now().year)])
bnr = models.ForeignKey('BalBankaccount', models.DO_NOTHING, db_column='BNR') # Field name made lowercase.
balance = models.DecimalField(db_column='BALANCE', max_digits=10, decimal_places=2) # Field name made lowercase.
available_balance = models.DecimalField(db_column='AVAILABLE_BALANCE', max_digits=10, decimal_places=2) # Field name made lowercase.
unavailable_balance = models.DecimalField(db_column='UNAVAILABLE_BALANCE', max_digits=10, decimal_places=2) # Field name made lowercase.
date_checked = models.DateTimeField(db_column='DATE_CHECKED') # Field name made lowercase.
created_at = models.DateTimeField(db_column='CREATED_AT') # Field name made lowercase.
class Meta:
managed = False
db_table = 'BAL_BALANCE'
unique_together = (('month', 'year', 'bnr'),)
我的 admin.py 看起来像这样
from django.contrib import admin
from .models import *
# Register your models here.
myModels = [BalBankaccount,BalCompany,BalIncome,BalInstitution,BalLocation]
admin.site.register(myModels)
class BalBalanceAdmin(admin.ModelAdmin):
list_display = ('month','year','bnr','balance','available_balance','unavailable_balance')
list_filter = ('bnr',)
ordering = ('year','month')
search_fields = ('bnr',)
admin.site.register(BalBalance,BalBalanceAdmin)
我怎样才能摆脱这个问题?感谢任何帮助
编辑:根据现有的内容或我测试的内容,django 会抛出不同的错误:
如果我自己声明 primary_key
,我会得到如下内容:
get() returned more than one BalBalance -- it returned 12!.
Get 只允许 return 1 个对象,但在这种情况下它 returns 12 个对象,因为我不允许在 django 中将我的 3 PK 声明为 PK...
如果我尝试通过添加 ID 来处理此错误,django 会抛出一个错误,指出字段 ID 丢失或存在完整性错误:
IntegrityError at /admin/balance/balbalance/add/ (1364, "Field 'ID'
doesn't have a default value")
如果我理解您收到的最后一个 (IntegrityError) 错误,我认为这是因为您手动添加了一个 id 字段作为主键。不要这样做,因为 Django 会自动为您创建一个自动递增的 id 主键,对于您自己没有 'override' 主键的任何模型。
因此请删除您添加的任何 'id' 或主键字段,然后将您的 unique_together 添加到元数据中。如果您 makemigrations
和 migrate
,这应该会按预期工作,并且您应该能够 BalBalance.objects.get(month=x, year=y, bnr=z)
并且可靠地只得到一个结果。这 实际上 与在所有 3 个字段中使用主键的初衷相同。
编辑:根据您的评论,我现在看到了潜在的问题,我没有注意到您在模型的 Meta 中设置了 managed=False。这意味着 django 不会为您 create/modify 而 table,因此上面建议的更改不会对结构产生任何影响。大概你有这个,因为你现在希望在 Django 管理界面中看到(并可能操作)现有 table 中的现有数据。
所以问题归结为:
- Django 将假设(除非您指定一个单独的字段作为主键)您已经在 table 上有一个自动递增的 id 列。你的 table.
上没有这个
- Django 不支持跨多个字段的主键,这是您在 table
上所拥有的
因此,解决方案(可能会让您很烦)是使数据库与 python 中定义的模型结构相匹配,使用我之前建议的结构。
因此:不要在模型上指定PK(Django会假设它有一个id列),然后手动操作数据库中的table添加一个自动递增的id列(和将其设置为主键,从其他 3 个字段中删除 PK)。接下来,在模型中的其他 3 个字段上指定 unique_together,然后添加并在数据库中的这些字段中添加唯一键。
一旦数据库反映了模型定义,您的痛苦就应该消除,管理员应该按预期使用您粘贴在问题中的代码。
当然,这取决于您是否将其他软件连接到该数据库 table,以及这些软件如何依赖 PK...您可能会遇到这些问题,但我不能肯定地说.
我的 Django 模型有问题,主要是主键问题。
我使用管理界面来管理我的数据。我已经建立了一个由 3 个主键组成的数据库,以减少多个条目 (year
、month
、bnr
)。
但是我的模型中没有涵盖这一点,因为 django 只接受一个主键。我尝试了一些东西,但 none 对我有帮助。管理界面总是给我一个错误。
- 删除模型中的所有主键
- 试图在我的 model/Database 中添加 ID 列,但未在我的数据库中声明为主键
- 添加了
unique_together
现在我的模型是这样的:
class BalBalance(models.Model):
month = models.PositiveIntegerField(default=datetime.datetime.now().month, validators=[MinValueValidator(1), MaxValueValidator(12)])
year = models.PositiveIntegerField(default=datetime.datetime.now().year, validators=[MinValueValidator(1990), MaxValueValidator(datetime.datetime.now().year)])
bnr = models.ForeignKey('BalBankaccount', models.DO_NOTHING, db_column='BNR') # Field name made lowercase.
balance = models.DecimalField(db_column='BALANCE', max_digits=10, decimal_places=2) # Field name made lowercase.
available_balance = models.DecimalField(db_column='AVAILABLE_BALANCE', max_digits=10, decimal_places=2) # Field name made lowercase.
unavailable_balance = models.DecimalField(db_column='UNAVAILABLE_BALANCE', max_digits=10, decimal_places=2) # Field name made lowercase.
date_checked = models.DateTimeField(db_column='DATE_CHECKED') # Field name made lowercase.
created_at = models.DateTimeField(db_column='CREATED_AT') # Field name made lowercase.
class Meta:
managed = False
db_table = 'BAL_BALANCE'
unique_together = (('month', 'year', 'bnr'),)
我的 admin.py 看起来像这样
from django.contrib import admin
from .models import *
# Register your models here.
myModels = [BalBankaccount,BalCompany,BalIncome,BalInstitution,BalLocation]
admin.site.register(myModels)
class BalBalanceAdmin(admin.ModelAdmin):
list_display = ('month','year','bnr','balance','available_balance','unavailable_balance')
list_filter = ('bnr',)
ordering = ('year','month')
search_fields = ('bnr',)
admin.site.register(BalBalance,BalBalanceAdmin)
我怎样才能摆脱这个问题?感谢任何帮助
编辑:根据现有的内容或我测试的内容,django 会抛出不同的错误:
如果我自己声明 primary_key
,我会得到如下内容:
get() returned more than one BalBalance -- it returned 12!.
Get 只允许 return 1 个对象,但在这种情况下它 returns 12 个对象,因为我不允许在 django 中将我的 3 PK 声明为 PK...
如果我尝试通过添加 ID 来处理此错误,django 会抛出一个错误,指出字段 ID 丢失或存在完整性错误:
IntegrityError at /admin/balance/balbalance/add/ (1364, "Field 'ID' doesn't have a default value")
如果我理解您收到的最后一个 (IntegrityError) 错误,我认为这是因为您手动添加了一个 id 字段作为主键。不要这样做,因为 Django 会自动为您创建一个自动递增的 id 主键,对于您自己没有 'override' 主键的任何模型。
因此请删除您添加的任何 'id' 或主键字段,然后将您的 unique_together 添加到元数据中。如果您 makemigrations
和 migrate
,这应该会按预期工作,并且您应该能够 BalBalance.objects.get(month=x, year=y, bnr=z)
并且可靠地只得到一个结果。这 实际上 与在所有 3 个字段中使用主键的初衷相同。
编辑:根据您的评论,我现在看到了潜在的问题,我没有注意到您在模型的 Meta 中设置了 managed=False。这意味着 django 不会为您 create/modify 而 table,因此上面建议的更改不会对结构产生任何影响。大概你有这个,因为你现在希望在 Django 管理界面中看到(并可能操作)现有 table 中的现有数据。
所以问题归结为:
- Django 将假设(除非您指定一个单独的字段作为主键)您已经在 table 上有一个自动递增的 id 列。你的 table. 上没有这个
- Django 不支持跨多个字段的主键,这是您在 table 上所拥有的
因此,解决方案(可能会让您很烦)是使数据库与 python 中定义的模型结构相匹配,使用我之前建议的结构。
因此:不要在模型上指定PK(Django会假设它有一个id列),然后手动操作数据库中的table添加一个自动递增的id列(和将其设置为主键,从其他 3 个字段中删除 PK)。接下来,在模型中的其他 3 个字段上指定 unique_together,然后添加并在数据库中的这些字段中添加唯一键。
一旦数据库反映了模型定义,您的痛苦就应该消除,管理员应该按预期使用您粘贴在问题中的代码。
当然,这取决于您是否将其他软件连接到该数据库 table,以及这些软件如何依赖 PK...您可能会遇到这些问题,但我不能肯定地说.