dana
dana

Reputation: 5208

django join querysets from multiple tables

If I have queries on multiple tables like:

d = Relations.objects.filter(follow = request.user).filter(date_follow__lt = last_checked)
r = Reply.objects.filter(reply_to = request.user).filter(date_reply__lt = last_checked)
article = New.objects.filter(created_by = request.user)
vote = Vote.objects.filter(voted = article).filter(date__lt = last_checked)

and I want to display the results from all of them ordered by date (I mean not listing all the replies, then all the votes, etc ). Somehow, I want to 'join all these results', in a single queryset. Is there possible?

Upvotes: 0

Views: 7363

Answers (2)

Bernhard Vallant
Bernhard Vallant

Reputation: 50776

In addition to to Sebastien's proposal number 2: Django actually has some built-in functionality that you could "abuse" for this; for the admin it has already a model that logs the user's actions and references the objects through a generic foreign key relation, I think you could just sub-class this model and use it for your purposes:

from django.contrib.admin.models import LogEntry, ADDITION
from django.utils.encoding import force_unicode
from django.contrib.contenttypes.models import ContentType

class MyLog(LogEntry):
    class Meta(LogEntry.Meta):
        db_table_name = 'my_log_table' #use another name here 

def log_addition(request, object):
    LogEntry.objects.log_action(
        user_id         = request.user.pk,
        content_type_id = ContentType.objects.get_for_model(object).pk,
        object_id       = object.pk,
        object_repr     = force_unicode(object),
        action_flag     = ADDITION
    )

You can now log all your notifications etc. where they happen with with log_addition(request, object) and filter the Log table than for your purposes! If you want to log also changes / deletions etc. you can make yourself some helper functions for that!

Upvotes: 1

sebpiq
sebpiq

Reputation: 7802

It seems like you need different objects to have common operations ...

1) In this case it might be better to abstract these properties in a super class... I mean that you could have an Event class that defines a user field, and all your other event classes would subclass this.

class Event(model.Model):
    user = models.ForeignKey(User)
    date = ...

class Reply(Event):
    #additional fields

class Vote(Event):
    #additional fields

Then you would be able to do the following

Event.objects.order_by("date") #returns both Reply, Vote and Event

Check-out http://docs.djangoproject.com/en/1.2/topics/db/models/#id5 for info on model inheritance.

2) You could also have an Event model with a generic relation to another object. This sounds cleaner to me as a Vote is conceptually not an "event". Check-out : http://docs.djangoproject.com/en/dev/ref/contrib/contenttypes/#id1

Anyway, I think your problem is a matter of design

Upvotes: 9

Related Questions