views:

342

answers:

2

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?

+5  A: 

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

sebpiq
yes, it seems to be the only solution. thanks!
dana
+1 for generic relations.
Daniel Roseman
anyway, if i'm using the 'subclass' method, how should i change my (above) queries to populate the new created models, and get variables to manipulate my template? i don't see an example in the djangoproject reference.Thanks!
dana
Actually, as I wrote and as other people confirmed, the solution 2 is better in my opinion.
sebpiq
ok:) i'll try it then ! :)
dana
+1  A: 

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!

lazerscience
well, that's interesting! i'll try this way! thanks! :)
dana