【发布时间】:2010-08-18 20:18:37
【问题描述】:
我有点 django / db brainfart。
换句话说,我试图想出一种更好的方法来表示我的项目中的 Address 对象。我有 5 或 6 个不同的模型,它们与地址(账单/运输/等)有一个或多个关联,我需要允许创建/修改/删除这些地址。我的第一个想法是为此使用管理员,因为它看起来很自然。
但是,我似乎不知道如何告诉管理员将可见的地址集限制为相关的特定模型(帐户/合作伙伴/发票)。我发现了一种非常讨厌的、不可行的、令人难以置信的维护方式,我将在下面展示。
我怎样才能有效地做到这一点(最好在管理员中)?我愿意建立对我来说更自然的 m2m 关系,并使用自定义视图/表单,但我想看看我在走那条路线之前是否错过了一些管理技巧。如果我走那条路,我想我需要使用 GenericRelation,这样我就不会得到大量的查找表(每个不同的实体一个)。
编辑:相同的地址可能用于不同的模型,并且对于特定模型的不同实例,但是如果一个地址被重复使用,我们必须跟踪谁在使用什么保持模型和/或实例之间的独立性。或者换句话说,在 m2m 关系中,我们可以通过中间表跟踪谁在使用什么。如果我们不使用查找表,那么我们需要始终复制 Address 实例,以便两个对象都有自己的副本。 (如果有编辑,我们需要确保我们不会更改其他任何人的预先存在的关系。换句话说,编辑实际上是在 m2m 案例中创建和重新分配。)
这是一个几乎可以作为一个空项目工作的示例,它显示了我希望在添加/编辑/删除期间如何隔离地址,但它也显示了解决方案是多么可怕。
models.py
>from django.db import models
class Account(models.Model):
name = models.CharField(max_length=200,blank=True)
#...
def __unicode__(self):
return u"%s - (%s)" %(self.name, self.address_set.all())
class Partner(models.Model):
name = models.CharField(max_length=200,blank=True)
discount = models.DecimalField(max_digits= 3, decimal_places=1, default=0)
#...
def __unicode__(self):
return u"%s - (%s)" %(self.name, self.address_set.all())
class Invoice(models.Model):
invoice_number = models.IntegerField(default=1)
#...
def __unicode__(self):
return u"%s - (%s)" %(self.invoice_number, self.address_set.all())
class Address(models.Model):
street = models.CharField(max_length=200,blank=True)
zip = models.CharField(max_length=10, verbose_name='Zip Code')
account = models.ForeignKey(Account, blank=True, null=True)
partner = models.ForeignKey(Partner, blank=True, null=True)
invoice = models.ForeignKey(Invoice, blank=True, null=True)
type = models.CharField(max_length=25, choices=(('B','Billing'),('S','Shipping')))
class Meta:
unique_together = (('type', 'account' ),
('type', 'partner' ),
('type', 'invoice' ),)
def __unicode__(self):
return "(%s) - %s %s" %(self.get_type_display(), self.street, self.zip)
admin.py
>from django.contrib import admin
from relationships.rels.models import Partner, Account, Address, Invoice
class AcctAddrInline(admin.TabularInline):
model = Address
extra = 1
max_num =3
exclude = ('partner', 'invoice')
class PartAddrInline(admin.TabularInline):
model = Address
extra = 1
max_num =3
exclude = ('account', 'invoice')
class InvAddrInline(admin.TabularInline):
model = Address
extra = 1
max_num =2
exclude = ('account', 'partner')
class AccountAdmin(admin.ModelAdmin):
inlines = [AcctAddrInline,]
class PartnerAdmin(admin.ModelAdmin):
inlines = [PartAddrInline,]
class InvoiceAdmin(admin.ModelAdmin):
inlines = [InvAddrInline,]
admin.site.register(Invoice, InvoiceAdmin)
admin.site.register(Partner, PartnerAdmin)
admin.site.register(Account, AccountAdmin)
admin.site.register(Address)
【问题讨论】:
-
您是否要为不同类型的模型重用相同的地址实例(即合作伙伴和帐户的相同地址)?相同模型的不同实例(即两个不同发票的相同地址)呢?
-
更新了主要问题陈述。
标签: django django-models django-admin