您可以使用通用关系通过手动创建消息和收件人之间的连接表来实现此功能:
from django.db import models
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
class Client(models.Model):
city = models.CharField(max_length=16)
sent_messages = generic.GenericRelation('Message',
content_type_field='sender_content_type',
object_id_field='sender_id'
)
received_messages = generic.GenericRelation('MessageRecipient',
content_type_field='recipient_content_type',
object_id_field='recipient_id'
)
class Meta:
abstract = True
class PersonClient(Client):
first_name = models.CharField(max_length=16)
last_name = models.CharField(max_length=16)
gender = models.CharField(max_length=1)
def __unicode__(self):
return u'%s %s' % (self.last_name, self.first_name)
class CompanyClient(Client):
name = models.CharField(max_length=32)
tax_no = models.PositiveIntegerField()
def __unicode__(self):
return self.name
class Message(models.Model):
sender_content_type = models.ForeignKey(ContentType)
sender_id = models.PositiveIntegerField()
sender = generic.GenericForeignKey('sender_content_type', 'sender_id')
msg_body = models.CharField(max_length=1024)
def __unicode__(self):
return u'%s...' % self.msg_body[:25]
class MessageRecipient(models.Model):
message = models.ForeignKey(Message)
recipient_content_type = models.ForeignKey(ContentType)
recipient_id = models.PositiveIntegerField()
recipient = generic.GenericForeignKey('recipient_content_type', 'recipient_id')
def __unicode__(self):
return u'%s sent to %s' % (self.message, self.recipient)
您可以像这样使用上述模型:
>>> person1 = PersonClient.objects.create(first_name='Person', last_name='One', gender='M')
>>> person2 = PersonClient.objects.create(first_name='Person', last_name='Two', gender='F')
>>> company = CompanyClient.objects.create(name='FastCompany', tax_no='4220')
>>> company_ct = ContentType.objects.get_for_model(CompanyClient)
>>> person_ct = ContentType.objects.get_for_model(person1)
>>> msg = Message.objects.create(sender_content_type=person_ct, sender_id=person1.pk, msg_body='Hey, did any of you move my cheese?')
>>> MessageRecipient.objects.create(message=msg, recipient_content_type=person_ct, recipient_id=person2.pk)
>>> MessageRecipient.objects.create(message=msg, recipient_content_type=company_ct, recipient_id=company.pk)
>>> MessageRecipient.objects.count()
2
正如您所看到的,这是一种更加冗长(复杂?)的解决方案。我可能会保持简单并采用Prariedogg在下面提供的解决方案。
received_messages
是Client
和Message
之间的多对多关系。这就是为什么它必须在MessageRecipient
上,因为没有GenericManyToManyField
。这样说通了吗? - elo80kasent_messages
也需要是泛型?因为Message
只有一种类型,所以它可以是一个普通关系吗?或者这个例子假设会添加多种类型的消息(比如电子邮件、短信、邮寄信件)? - JHSForeignKey
关系。不同类型的客户(如Company
、Person
等)可以发送消息,因此sender
是一个GenericForeignKey
。sent_messages
模型反映了这种关系的反向关系,因此它本身是一个GenericRelation
。 - elo80ka