Django从多个表中检索数据而没有外键关系

时间:2014-09-13 13:35:27

标签: python mysql django orm

我有以下三个模型

class Post(models.Model):
    category_type = models.CharField(max_length=10)
    participant_id = models.IntegerField()
    title = models.CharField(max_length=200)

class Book(models.Model):
    title = models.CharField(max_length=50)
    author = models.CharField(max_length=500)
    price = models.IntegerField(default=0)

class Instrument(models.Model):
    title = models.CharField(max_length=50)
    price = models.IntegerField(default=0)

Post模型中的category_type可以是“book”或“instrument”,这些类别将来会增加。

Post表中的participant_id列根据category_type引用Book表或Instrument表的主键。

现在我想从数据库中检索所有帖子和相关数据。

在MySql中,我可以这样做

select post.title,book.title from post,book where ((post.category_type="book" and post.participant_id=book.id))
union
select post.title,instrument.title from post,instrument where ((post.category_type="instrument" and post.participant_id=instrument.id))

但我无法使用django这样做,因为我不能拥有外键关系。

非常感谢任何帮助。

更新:我尝试使用Django的泛型关系修改Post表,如下所示

class Post(models.Model):
    category_type = models.CharField(max_length=10)
    participant_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    participant_object = GenericForeignKey('content_type', 'participant_id')    
    title = models.CharField(max_length=200)

然后我发出了以下查询

Post.objects.filter(content_type=ContentType.objects.get_for_model(Book))

但是这给了我错误

FieldError: Cannot resolve keyword 'content_type' into field. Choices are: category_type, id,  participant_id, title

如果我无法在条件中指定数据,如何检索数据。

1 个答案:

答案 0 :(得分:1)

我使用了Timmy建议的Django的通用关系。以下是Post

的修改模型
class Post(models.Model):
    category_type = models.CharField(max_length=10)
    participant_id = models.PositiveIntegerField()
    content_type = models.ForeignKey(ContentType)
    participant_object = GenericForeignKey('content_type', 'participant_id')    
    title = models.CharField(max_length=200)

然后我发出了以下查询

Post.objects.filter(content_type=ContentType.objects.get_for_model(Book))

这给了我正确的结果 修改模型后不要忘记重建数据库,否则会出错。