使用遗留数据库时 Django MultipleObjectsReturned
Django MultipleObjectsReturned while using a legacy database
我正在使用 Djano 开发一个简单的 Web 应用程序来显示和管理数据库数据。我连接了一个 MySQL 数据库并使用 inspectdb 根据数据库表自动生成一个模型,这就是我得到的结果,看起来不错。
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey has `on_delete` set to the desired behavior.
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from __future__ import unicode_literals
from django.core.exceptions import MultipleObjectsReturned
from django.db import models
class Booking(models.Model):
class Meta:
managed = False
db_table = 'Booking'
unique_together = (('hotelno', 'guestno', 'datefrom'),)
hotelno = models.OneToOneField('Hotel', models.DO_NOTHING, db_column='hotelNo', primary_key=True) # Field name made lowercase.
guestno = models.IntegerField(db_column='guestNo') # Field name made lowercase.
datefrom = models.DateTimeField(db_column='dateFrom') # Field name made lowercase.
dateto = models.DateTimeField(db_column='dateTo', blank=True, null=True) # Field name made lowercase.
roomno = models.OneToOneField('Room', models.DO_NOTHING, db_column='roomNo') # Field name made lowercase.
list_display =
#def __str__(self):
# return ("".join(hotelno) + "".join(guestno) + "".join(datefrom))
class Guest(models.Model):
guestno = models.AutoField(db_column='guestNo', primary_key=True) # Field name made lowercase.
guestname = models.CharField(db_column='guestName', max_length=255) # Field name made lowercase.
guestaddress = models.CharField(db_column='guestAddress', max_length=255, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Guest'
class Hotel(models.Model):
hotelno = models.AutoField(db_column='hotelNo', primary_key=True) # Field name made lowercase.
hotelname = models.CharField(db_column='hotelName', max_length=255, blank=True, null=True) # Field name made lowercase.
city = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'Hotel'
class Room(models.Model):
roomno = models.IntegerField(db_column='roomNo', primary_key=True) # Field name made lowercase.
hotelno = models.ForeignKey(Hotel, models.DO_NOTHING, db_column='hotelNo') # Field name made lowercase.
type = models.CharField(max_length=255, blank=True, null=True)
price = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'Room'
unique_together = (('roomno', 'hotelno'),)
在这个应用程序的 admin.py 文件中,我包含了这样的模型,这样我至少可以看到那里的数据。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.
from .models import Hotel, Room, Guest, Booking
admin.site.register(Hotel)
admin.site.register(Room)
admin.site.register(Guest)
admin.site.register(Booking)
当我访问默认的 Django 管理页面时,我会看到 tables registered on admin page.
我点击预订并看到 multiple records, without names (for other reasons), but if I click on one of them I get the MultipleObjectsReturned Error
我已经阅读了我能找到的所有内容,而我能找到的最接近原因的原因与某些模型中的复合键有关。但是,同样,我不知道这是否是真正的原因,我也可能遗漏了什么?我不知道。
我猜是因为 Booking
table 的数据与你的模型声明不一致。 Django 的管理详细视图通过主键检索模型。
您将 hotelno
标记为 PK:
hotelno = models.OneToOneField('Hotel', models.DO_NOTHING, db_column='hotelNo', primary_key=True)
由于 Booking
table 中已经存在一些数据,您必须确保 hotelno
值(hotelNo 列)是唯一的,否则您将得到 MultipleObjectsReturned
异常对于非唯一的 pk 值。还要确保您已阅读文档的这一部分 https://docs.djangoproject.com/en/1.11/ref/models/options/#managed
看起来您的预订 table 没有主键,inspectdb 在将其影响到您预订的 hotelno 列时猜错了 table。
当管理员尝试通过其 ID 获取记录时,它会得到多个结果,因为不同的预订可以多次引用同一家酒店。
我会在预订模型上做什么:
- 将 hotelno 和 roomno 更改为 ForeignKey
- 删除 hotelno 上的主节点
新问题是现在您的模型没有主键。 Django 不允许这样做。如果您可以更改 MySQL table 添加一个主键列并相应地更改预订模型。如果你不能改变 table 我认为没有简单的方法让它起作用。
我正在使用 Djano 开发一个简单的 Web 应用程序来显示和管理数据库数据。我连接了一个 MySQL 数据库并使用 inspectdb 根据数据库表自动生成一个模型,这就是我得到的结果,看起来不错。
# This is an auto-generated Django model module.
# You'll have to do the following manually to clean this up:
# * Rearrange models' order
# * Make sure each model has one field with primary_key=True
# * Make sure each ForeignKey has `on_delete` set to the desired behavior.
# * Remove `managed = False` lines if you wish to allow Django to create, modify, and delete the table
# Feel free to rename the models, but don't rename db_table values or field names.
from __future__ import unicode_literals
from django.core.exceptions import MultipleObjectsReturned
from django.db import models
class Booking(models.Model):
class Meta:
managed = False
db_table = 'Booking'
unique_together = (('hotelno', 'guestno', 'datefrom'),)
hotelno = models.OneToOneField('Hotel', models.DO_NOTHING, db_column='hotelNo', primary_key=True) # Field name made lowercase.
guestno = models.IntegerField(db_column='guestNo') # Field name made lowercase.
datefrom = models.DateTimeField(db_column='dateFrom') # Field name made lowercase.
dateto = models.DateTimeField(db_column='dateTo', blank=True, null=True) # Field name made lowercase.
roomno = models.OneToOneField('Room', models.DO_NOTHING, db_column='roomNo') # Field name made lowercase.
list_display =
#def __str__(self):
# return ("".join(hotelno) + "".join(guestno) + "".join(datefrom))
class Guest(models.Model):
guestno = models.AutoField(db_column='guestNo', primary_key=True) # Field name made lowercase.
guestname = models.CharField(db_column='guestName', max_length=255) # Field name made lowercase.
guestaddress = models.CharField(db_column='guestAddress', max_length=255, blank=True, null=True) # Field name made lowercase.
class Meta:
managed = False
db_table = 'Guest'
class Hotel(models.Model):
hotelno = models.AutoField(db_column='hotelNo', primary_key=True) # Field name made lowercase.
hotelname = models.CharField(db_column='hotelName', max_length=255, blank=True, null=True) # Field name made lowercase.
city = models.CharField(max_length=255, blank=True, null=True)
class Meta:
managed = False
db_table = 'Hotel'
class Room(models.Model):
roomno = models.IntegerField(db_column='roomNo', primary_key=True) # Field name made lowercase.
hotelno = models.ForeignKey(Hotel, models.DO_NOTHING, db_column='hotelNo') # Field name made lowercase.
type = models.CharField(max_length=255, blank=True, null=True)
price = models.IntegerField(blank=True, null=True)
class Meta:
managed = False
db_table = 'Room'
unique_together = (('roomno', 'hotelno'),)
在这个应用程序的 admin.py 文件中,我包含了这样的模型,这样我至少可以看到那里的数据。
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.
from .models import Hotel, Room, Guest, Booking
admin.site.register(Hotel)
admin.site.register(Room)
admin.site.register(Guest)
admin.site.register(Booking)
当我访问默认的 Django 管理页面时,我会看到 tables registered on admin page. 我点击预订并看到 multiple records, without names (for other reasons), but if I click on one of them I get the MultipleObjectsReturned Error
我已经阅读了我能找到的所有内容,而我能找到的最接近原因的原因与某些模型中的复合键有关。但是,同样,我不知道这是否是真正的原因,我也可能遗漏了什么?我不知道。
我猜是因为 Booking
table 的数据与你的模型声明不一致。 Django 的管理详细视图通过主键检索模型。
您将 hotelno
标记为 PK:
hotelno = models.OneToOneField('Hotel', models.DO_NOTHING, db_column='hotelNo', primary_key=True)
由于 Booking
table 中已经存在一些数据,您必须确保 hotelno
值(hotelNo 列)是唯一的,否则您将得到 MultipleObjectsReturned
异常对于非唯一的 pk 值。还要确保您已阅读文档的这一部分 https://docs.djangoproject.com/en/1.11/ref/models/options/#managed
看起来您的预订 table 没有主键,inspectdb 在将其影响到您预订的 hotelno 列时猜错了 table。
当管理员尝试通过其 ID 获取记录时,它会得到多个结果,因为不同的预订可以多次引用同一家酒店。
我会在预订模型上做什么:
- 将 hotelno 和 roomno 更改为 ForeignKey
- 删除 hotelno 上的主节点
新问题是现在您的模型没有主键。 Django 不允许这样做。如果您可以更改 MySQL table 添加一个主键列并相应地更改预订模型。如果你不能改变 table 我认为没有简单的方法让它起作用。