【发布时间】: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 将两个键都导入为
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