【问题标题】:Getting "Please correct the errors below" when saving changes in django admin在 django admin 中保存更改时出现“请更正以下错误”
【发布时间】:2017-02-05 17:04:50
【问题描述】:

模型是从以下带有“python manage.py inspectdb --database=mydatabasename”的mysql db创建的:

CREATE TABLE `authors` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

CREATE TABLE `books` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `titel` varchar(45) DEFAULT NULL,
  `year` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

CREATE TABLE `authors_books` (
  `author_id` int(11) NOT NULL,
  `book_id` int(11) NOT NULL,
  KEY `fk_authors_books_2_idx` (`book_id`),
  KEY `fk_authors_books_1` (`author_id`),
  CONSTRAINT `fk_authors_books_1` FOREIGN KEY (`author_id`) REFERENCES `authors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
  CONSTRAINT `fk_authors_books_2` FOREIGN KEY (`book_id`) REFERENCES `books` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `awards` (
  `author` int(11) NOT NULL,
  `award_name` varchar(45) NOT NULL,
  `year` int(11) DEFAULT NULL,
  PRIMARY KEY (`author`,`award_name`),
  CONSTRAINT `fk_awards_1` FOREIGN KEY (`author`) REFERENCES `authors` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

模型如下所示:

class Authors(models.Model):
    name = models.CharField(max_length=45, blank=True, null=True)
    birthday = models.DateField(blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'authors'
        verbose_name_plural = 'Authors'  

    def __unicode__(self):
        return self.name


class AuthorsBooks(models.Model):
    author_id = models.OneToOneField('Authors', models.DO_NOTHING, db_column='author_id', primary_key=True)
    book_id = models.OneToOneField('Books', models.DO_NOTHING, db_column='book_id', primary_key=True)

    class Meta:
        managed = True
        db_table = 'authors_books'
        unique_together = (('author_id', 'book_id'),)
        verbose_name_plural = 'Author Books'         


class Awards(models.Model):
    author = models.OneToOneField('Authors', models.DO_NOTHING, db_column='author', primary_key=True)
    award_name = models.CharField(max_length=45)
    year = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'awards'
        unique_together = (('author', 'award_name'),)
        verbose_name_plural = 'Awards' 


class Books(models.Model):
    titel = models.CharField(max_length=45, blank=True, null=True)
    year = models.IntegerField(blank=True, null=True)

    class Meta:
        managed = True
        db_table = 'books'
        verbose_name_plural = 'Books' 

    def __unicode__(self):
        return '{} - {}'.format(self.titel, self.year)

在 AuthorsBooks 类中,我已将两个外键更改为 OneToOneFields。

我的 admin.py 看起来像这样:

from django.contrib import admin
from myapp.models import Authors
...
class AwardsInline(admin.TabularInline):
    model = Awards

class AuthorsBooksInline(admin.TabularInline):
    model = AuthorsBooks

class AuthorsAdmin(admin.ModelAdmin):
    list_display = ("name", "birthday" )
    inlines = (AwardsInline, AuthorsBooksInline)

class BooksAdmin(admin.ModelAdmin):
    list_display = ("id", "titel", "year" )

admin.site.register(Authors, AuthorsAdmin)
admin.site.register(Books, BooksAdmin)

当我尝试在 django 管理页面上更改作者时,我收到以下错误:

【问题讨论】:

  • 为什么将它们改为一对一?根据定义,这意味着您只能在关系的每一方拥有一个项目,这就是为什么它抱怨但又是独一无二的。
  • 这是一个组合主键,但我不知道如何在 django 模型中定义它。 Django 将两个键都导入为author = models.ForeignKey(Authors, models.DO_NOTHING)book = models.ForeignKey('Books', models.DO_NOTHING),然后添加一个id 字段作为数据库中不存在的主键。我发现最好的东西是 OneToOneField...也许您有更好的解决方案?
  • 你可能想要的是 m2m 表和 unique_together 这两列 docs.djangoproject.com/en/1.10/topics/db/examples/many_to_many
  • 谢谢提示,我试试看。

标签: django django-models django-admin


【解决方案1】:

我让它工作的唯一方法是不使用“复合”或“复合”主键。我添加了一个列 id 作为 mysql 表 Awards 和 authors_books 的主键。 然后我又改回来了:

 class AuthorsBooks(models.Model):
    author_id = models.OneToOneField('Authors', models.DO_NOTHING, db_column='author_id', primary_key=True)
    book_id = models.OneToOneField('Books', models.DO_NOTHING, db_column='book_id', primary_key=True)
    ...

收件人:

class AuthorsBooks(models.Model):
    author_id = models.ForeignKey('Authors', models.DO_NOTHING, db_column='author_id')
    book_id = models.ForeignKey('Books', models.DO_NOTHING, db_column='book_id') 
    ...

class Awards(models.Model):
    author = models.OneToOneField('Authors', models.DO_NOTHING, db_column='author', primary_key=True)
    award_name = models.CharField(max_length=45)
    year = models.IntegerField(blank=True, null=True)
    ...

class Awards(models.Model):
  author = models.ForeignKey('Authors2', models.DO_NOTHING, db_column='author')
  award_name = models.CharField(max_length=45)
  year = models.IntegerField(blank=True, null=True)
  ...

我没有找到 ManyToManyField 的解决方案,总是同样的问题。 我认为原因是这样的:

目前 Django 模型仅支持该集合中的单个列, 否认许多表的自然主键是 多列。 Django 目前不能使用这些模式;他们 必须改为引入冗余的单列键(“代理” 键),强制应用程序进行任意和其他不必要的操作 选择在任何给定实例中为表使用哪个键。

https://code.djangoproject.com/wiki/MultipleColumnPrimaryKeys

【讨论】:

    猜你喜欢
    • 2019-11-21
    • 1970-01-01
    • 2021-12-11
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 1970-01-01
    • 1970-01-01
    • 2022-08-24
    相关资源
    最近更新 更多