在Django Admin中对多个模型反向内联

8 投票
2 回答
3566 浏览
提问于 2025-04-17 08:49

假设我有一些Django模型,像这样:

class Address(models.Model):
    pass

class Person(models.Model):
    address = models.ForeignKey(Address)

class Store(models.Model):
    address = models.ForeignKey(Address)

class Company(models.Model):
    address = models.ForeignKey(Address)

所以,在管理界面中,我希望能够编辑一个人的信息,并且把地址信息放在同一页面上。

我知道这是可以做到的,

class Address(models.Model):
    person  = models.ForeignKey(Person, blank=True)
    store   = models.ForeignKey(Store, blank=True)
    company = models.ForeignKey(Company, blank=True)

class Person(models.Model):
    pass

class Store(models.Model):
    pass

class Company(models.Model):
    pass

然后我可以做一些常规的操作,

class AddressInline(admin.TabularInline):
    model = Address

class PersonAdmin(admin.ModelAdmin):
    model = Person
    inlines = (AddressInLine,)

class CompanyAdmin(admin.ModelAdmin):
    and so on

但是这样的话,每个人就会有多个地址,这让我觉得我的地址模型不太对劲。

任何帮助都会很感激。

2 个回答

3

把类 AddressInline(admin.TabularInline) 改成类 AddressInline(admin.StackedInline) 会让地址的输入框看起来不那么像可以添加多个地址。

如果你希望每个 AddressInline 只允许填写一个地址,可以把 AddressInline.max_num 设置为 1。

如果你希望在没有相关地址时显示一个空白的地址表单,可以把 AddressInline.extra 设置为 1。

文档链接: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#inlinemodeladmin-options

6

试试下面这个:

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Address(models.Model):
    object_id    = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    of           = generic.GenericForeignKey('content_type', 'object_id' )

class Person(models.Model):
    pass

class Store(models.Model):
    pass

class Company(models.Model):
    pass

然后你可以这样做:

from django.contrib import admin
from django.contrib.contenttypes import generic

class AddressInline(generic.GenericStackedInline):
    model   = Address
    max_num = 1

class PersonAdmin(admin.ModelAdmin):
    model = Person
    inlines = (AddressInLine,)

class CompanyAdmin(admin.ModelAdmin):
    and so on

admin.site.register(Person, PersonAdmin)

撰写回答