KVISH
KVISH

Reputation: 13208

Django ORM join with another table

I have a table known as messages. In my application, users can send different type of messages. Like forwarding an event, etc. As such, I have columns type and value in that table.

What I want to do is for a particular type, goto a particular table and make sure the value is valid (typically this maps to the id of that table). There could be multiple types, and each one has to be mapped to a different table. Is there a way to logically write this in the built in django ORM? Right now I'm only seeing this feasible if I use straight SQL, which I would rather not if I can get away with it...

Right now I'm doing something like:

Messages.objects.all().filter(Q(user_id=id))...etc

I want to add to the statement above checking the type and for the particular type, check the table associated with it.

Upvotes: 0

Views: 294

Answers (2)

dokkaebi
dokkaebi

Reputation: 9190

You may just want to define a multi-table inheritance structure. This gets you the same result in that you have multiple types of messages and field inheritance, but you don't have to mess with a type field at all.

class Message(models.Model):
    value = models.CharField(max_length=9000)

class Event(Message):
    pass

class Tweet(Message):
    pass

In view post handler:

...
if request.POST['type'] == 'event':
    Event.objects.create(value=request.POST['value'])
elif request.POST['type'] == 'tweet':
    Tweet.objects.create(value=request.POST['value'])
...

Then, get your objects:

all_tweets = Tweet.objects.all()
all_messages = Message.objects.all()

for message in all_messages:
    try:
        event = message.event
    except Event.DoesNotExist:
        # this message is not an Event
        pass

If this sort of structure doesn't work for you, there are two other styles of Model inheritance supported by Django: Abstract base classes and Proxy models. You could also hold a GenericForeignKey as suggested by @AndrewGorcester.

Upvotes: 0

Andrew Gorcester
Andrew Gorcester

Reputation: 19983

It sounds like you have a "polymorphic association". There are a couple ways to do analogous things in Django, but I think the one that most closely matches what you described is the contenttypes module, which uses separate columns for the type and for the value as in your application.

Upvotes: 1

Related Questions