Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django - get list of objects by filtering a list of objects

I am creating a user activity streams.

models for activity:

class Activity(models.Model):
    actor = models.ForeignKey(User)
    action = models.CharField(max_length=100)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')
    pub_date = models.DateTimeField(auto_now_add=True, auto_now=False)

model for Relationship:

class Person(models.Model):
    user = models.OneToOneField(User)
    relationships = models.ManyToManyField('self', through='Relationship', 
                                           symmetrical=False, 
                                           related_name='related_to')
RELATIONSHIP_FOLLOWING = 1
RELATIONSHIP_BLOCKED = 2
RELATIONSHIP_STATUSES = (
    (RELATIONSHIP_FOLLOWING, 'Following'),
    (RELATIONSHIP_BLOCKED, 'Blocked'),
)

class Relationship(models.Model):
    from_person = models.ForeignKey(Person, related_name='from_people')
    to_person = models.ForeignKey(Person, related_name='to_people')
    status = models.IntegerField(choices=RELATIONSHIP_STATUSES)  

def get_relationships(self, status):
    return self.relationships.filter(
        to_people__status=status, 
        to_people__from_person=self)

def get_following(self):
    return self.get_relationships(RELATIONSHIP_FOLLOWING)

In the views:

def home(request):
    if request.user.is_authenticated():
        user = request.user
        userP = Person.objects.get_or_create(user=user)
        userP = userP[0]
        following = userP.get_following()
        activities = Activity.objects.filter(actor__in=following)
        if request.POST:
            form = StatusForm(request.POST, request.FILES)
            if form.is_valid():
                if form.cleaned_data:
                    status = form.save(commit=False)
                    status.user = user
                    status.save()
                    return HttpResponseRedirect('/')

Scenario

  • user is following user2 and user3
  • user2 is following user and user3
  • user3 is following user and user2

Since I am filtering activities with actor=user and not actor=userP (which is an object of type user.person). How will I get a list of user object from the list get_following() method and not of user.person object.

I can however loop through each of the following like so:

    following = userP.get_following()
    users = []
    for u in following:
        users.append(u.user)
    users.append(user)
    activities = Activity.objects.filter(actor__in=users)

But I am hoping that there will be another better way to do it?

Please guide me. Your help will be very much appreciated. Thank you.

like image 344
Kakar Avatar asked Feb 11 '23 02:02

Kakar


1 Answers

Use the queryset's values_list() method:

activities = Activity.objects.filter(actor__in=
                                     following.values_list('user', flat=True))

If you want to add another user to actors list then you have to convert valies_list from queryset to regular python list:

actors = list(following.values_list('user', flat=True)) + [user.id]
activities = Activity.objects.filter(actor__in=actors)
like image 150
catavaran Avatar answered Feb 13 '23 15:02

catavaran