3

Suppose this is a model for an app Blog:

class Blog(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateTimeField(default=datetime.now)
    creator = models.ForeignKey(User)
    content = BleachField()

And this is another model for an app Status:

class Status(models.Model):
    content = BleachField()
    pub_date = models.DateTimeField(default=datetime.now)
    creator = models.ForeignKey(User)

How do I come up with something like this:

from blog.models import Blog
from status.models import Status

blog = Blog.objecs.all()
status = Status.objects.all()
all = blog | status

And display all the updates for the user in the template.

updates = user.all_set.all()

Edit:

So that in the templates I can do, something like this:

{% for each in all %}
    ....
{% endfor %}

What I wan't is that, in the home page, I would like to display the updates of all the user's activity in the latest order,

Eg:

'User updated with new status: blah blah'
'User published a new Blog'
'User published a new Blog'

like in many other social networking sites. And not to display them both separately. And similarly in the user's profile, display all the activities of that particular User.

Robin
  • 5,366
  • 17
  • 57
  • 87
  • You can't combine them at SQL level for sure, because the required schema projections are different (an outstanding difference, the number of queried columns is different). – Stefano Sanfilippo Nov 03 '13 at 11:43
  • Are you just looking to merge the two querysets? http://stackoverflow.com/questions/431628/how-to-combine-2-or-more-querysets-in-a-django-view – Timmy O'Mahony Nov 03 '13 at 12:55
  • If you want to have an activity feed you should look into an app that accomplishes that like [`django-activity-stream`](https://www.google.com/search?q=django+activity+feed) as you will need to incorporate nouns ("updated" or "published") and actors ("bob" or "jane") – Timmy O'Mahony Nov 03 '13 at 12:56
  • @TimmyO'Mahony OK. I think django-activity-stream is what I am looking for. Bur can I filter like, whether or not to display the activities only to the follower and so on, using django-activity-stream? – Robin Nov 03 '13 at 15:06

2 Answers2

1

You should use django proxy models for this, here's the documentation.

Here's an example:

class BlogAndStatus(models.Model):
    title = models.CharField(max_length=200)
    pub_date = models.DateField()
    creator = models.ForeignKey(User)
    content = models.TextField()
    is_blog = models.BooleanField(default=False)
    is_status = models.BooleanField(default=False)


class BlogManager(models.Manager):
    def get_query_set(self):
        return super(BlogManager, self).get_query_set().filter(is_status=True)


class Blog(BlogAndStatus):
    objects = BlogManager()

    class Meta:
        proxy = True

    def save(self, *args, **kwargs):
        self.is_blog = True
        return super(Blog, self).save(*args, **kwargs)


class StatusManager(models.Manager):
    def get_query_set(self):
        return super(StatusManager, self).get_query_set().filter(is_blog=True)


class Status(BlogAndStatus):
    objects = StatusManager()

    class Meta:
        proxy = True

    def save(self, *args, **kwargs):
        self.is_status = True
        return super(Status, self).save(*args, **kwargs)

You can get all objects with:

BlogAndStatus.objects.all()

or, using the manager, just Status with:

Status.objects.all()

You can use regular model forms in your forms.py, just make sure you set the field 'is_blog' or 'is_status' as True. An example for Blog:

class BlogForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(BlogForm, self).__init__(*args, **kwargs)
        self.initial['is_blog'] = True

    class Meta:
        model = Blog
        fields = ('title', 'content', 'is_blog')
        widget = {'is_blog': forms.HiddenInput()}
danielcorreia
  • 2,108
  • 2
  • 24
  • 36
-1

I am not sure why you have such a weird model; but the best you can do is this:

from django.shortcuts import render

def foo(request):
   photo = Photo.objects.filter(creator=request.user)
   status = Status.objects.filter(creator=request.user)
   context = {'photo': photo, 'status': status}
   return render(request, 'template.html', context)

Then in your template:

<h4>Photos:</h4>
  <ul>
  {% for p in photo %}
     <li>{{ p }}</li>
  {% endfor %}
  </ul>
<h4>Status:</h4>
  <ul>
  {% for s in status %}
     <li>{{ s }}</li>
  {% endfor %}
  </ul>
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • Yes, I could have done this. But I don't want to display them separately. I want to display them according to latest activity. Please check the edit. – Robin Nov 03 '13 at 12:42