Django 管理内联是围绕着构建的,这一点是无法回避的事实ForeignKey
字段(或ManyToManyField
, OneToOneField
)。但是,如果我理解您的目标,那就是避免管理您之间的“日期完整性”Diary.day
and Sleep.start_time
字段,即外键关系中的冗余,当该关系实际上由Diary.day == Sleep.start_time.date()
姜戈ForiegnKey
字段有一个to_field 属性 https://docs.djangoproject.com/en/1.11/ref/models/fields/#django.db.models.ForeignKey.to_field允许 FK 为列建立索引id
。但是,由于您有一个DateTimeField
in Sleep
and a DateField
in Diary
,我们需要将其分开DateTimeField
向上。也ForeignKey
必须与关系的“1”侧唯一的事物相关。Diary.day
需要设置unique=True
.
在这种方法中,您的模型看起来像
from django.db import models
# Parent
class Diary(models.Model):
day = models.DateField(unique=True)
activities = models.TextField()
# Child
class Sleep(models.Model):
diary = models.ForeignKey(Diary, to_field='day', on_delete=models.CASCADE)
start_time = models.TimeField()
end_time = models.DateTimeField()
然后你的admin.py
is just
from django.contrib import admin
from .models import Sleep, Diary
class SleepInline(admin.TabularInline):
model=Sleep
@admin.register(Diary)
class DiaryAdmin(admin.ModelAdmin):
inlines = (SleepInline, )
虽然Sleep.start_time
不再有日期,Django Admin 完全符合您的期望,并且避免了“日期冗余”:
提前考虑一个更真实(且有问题)的用例,假设每个用户每天可以有 1 篇日记:
class Diary(models.Model):
user = models.ForeignKey(User)
day = models.DateField()
activities = models.TextField()
class Meta:
unique_together = ('user', 'day')
有人想写一些类似的东西
class Sleep(models.Model):
diary = models.ForeignKey(Diary, to_fields=['user', 'day'], on_delete=models.CASCADE)
然而,Django 1.11 中没有这样的功能,我也找不到任何关于添加该功能的认真讨论。当然,Postgres 和其他 SQL DBMS 中允许使用复合外键。我从 Django 消息来源得到的印象是他们保持开放的选择:https://github.com/django/django/blob/stable/1.11.x/django/db/models/fields/lated.py#L621 https://github.com/django/django/blob/stable/1.11.x/django/db/models/fields/related.py#L621暗示未来的实施。
最后,https://pypi.python.org/pypi/django-composite-foreignkey https://pypi.python.org/pypi/django-composite-foreignkey乍一看很有趣,但并没有创建“真正的”复合外键,也不能与 Django 的管理一起使用。