问题
I want to create a custom object list in the view and pass it to the template. In the template I want to loop over the list and display the information.
My models are
class CustomUser(AbstractUser):
def __str__(self):
return self.email
class Post(models.Model):
author = models.ForeignKey(CustomUser,on_delete=models.CASCADE,)
text = models.TextField()
created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
post_url = models.URLField(max_length = 200, blank = True)
slug = models.SlugField(unique=True, blank=True)
class subscription(models.Model):
creator = models.ForeignKey(CustomUser,default=None, null=True,on_delete=models.CASCADE,related_name='creator',)
booster = models.ForeignKey(CustomUser,default=None, null=True,on_delete=models.CASCADE,related_name='booster')
sub_value = models.FloatField(blank = True)
sub_id = models.TextField(blank = True)
status = models.BooleanField(default=False)
dateSubscribed = models.DateTimeField(default=timezone.now)
dateSubscriptionEnded = models.DateTimeField(default=timezone.now)
paymentCount = models.FloatField(default= 0)
I want to filter objects from subscription model like below
subs = subscription.objects.filter(booster = request.user)
Then find creators in the above subs object list and for each creator get the name, numbers Posts, and number of Subscribers. Add this to custom list and pass it to the template to loop over and display the information in the template. Can someone help me how to create this custom list. Thanks!
回答1:
Ok so here are the basics minus the subscribers because I don't see the relation clearly. This is how to parse the name and the number of posts. \
my_list = []
for sub in subs:
name = sub.creator.name
auth_id = sub.creator.id
posts = Post.objects.filter(author=auth_id)
num_of_posts = len(posts)
my_list.append({
'name':name,
'post_count': num_of_posts,
})
then you would pass mylist thru the template context.
回答2:
It is a common mistake to name the related_name=… parameter [Django-doc] to the same value as the name of the field. The related_name parameter however is the name of the reverse relation Django will automatically add. So here it means a relation to access for example the related subscription objects of a given CustomUser.
Therefore it makes more sense to rename these, for example like:
class Subscription(models.Model):
creator = models.ForeignKey(
CustomUser,
default=None,
null=True,
on_delete=models.CASCADE,
related_name='created_subscriptions'
)
booster = models.ForeignKey(
CustomUser,
default=None,
null=True,
on_delete=models.CASCADE,
related_name='boosted_subscriptions'
)
sub_value = models.FloatField(blank=True)
sub_id = models.TextField(blank =True)
status = models.BooleanField(default=False)
dateSubscribed = models.DateTimeField(default=timezone.now)
dateSubscriptionEnded = models.DateTimeField(default=timezone.now)
paymentCount = models.FloatField(default=0)
Next we can make a query where:
from django.db.models import Count
CustomUser.objects.filter(
created_subscriptions__booster=request.user
).annotate(
number_of_posts=Count('post', distinct=True)
)
This is a QuerySet of CustomUsers where each CustomUser that arises from this QuerySet has an extra attribute .number_of_posts that contains the number of posts. You thus can iterate over the queryset directly in the template.
来源:https://stackoverflow.com/questions/58894056/django-create-custom-object-list-in-the-view-and-pass-it-to-template-to-loop-o