简体   繁体   中英

Django retrieve data from multiple tables without foreign key relationship

I have the following three Models

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)

Here category_type in Post model can be "book" or "instrument" and these categories can increase in the future.

The participant_id column in Post table references the primary key of either Book table or Instrument table based on the category_type.

Now I want to retrieve all the posts and associated data from database.

In MySql, I can do it like this

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))

But I am unable to do it using django as I cannot have foreign key relationship.

Any help is highly appreciated.

Update: I tried with Django's generic relations by modifying the Post table as below

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)

And then I issued the following query

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

But this gives me error

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

How can I retrieve the data if I cannot specify it in the condition.

I used Django's generic relations as suggested by Timmy. Following is the modified model for 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)

And then I issued the following query

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

This gave me the correct results Don't forget to rebuild your DB after modifying the model otherwise you will get error.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM