如何使forloops仅通过Django Python中的唯一值运行

时间:2018-07-28 19:14:20

标签: django python-3.x django-models django-views

简介:我有一个名为event的模型,该模型具有一个ForeignKey post。它的工作方式是: 示例 。用户创建了一个名为“ Solar Eclipse”的帖子。任何数量的用户都可以基于该帖子创建事件。因此,如果有人去该帖子详细信息页面。它有一个名为See all Events的按钮,他们可以看到所有主持Solar Eclipse Event的人。假设有5个帖子(涉及不同主题,例如滑雪,远足等),其中3个帖子各有10个活动。 2个帖子没有活动。在我的主页上,有一个部分显示“事件”。在首页的事件部分,我想显示3个帖子,其中包含事件而不是30个事件。我该怎么做。这样我就不会多次访问数据库

下面是 views.py

class EventView(ListView):
    model = Event
    template_name = 'home.html'    
    context_object_name = 'all_events' 

    def get_queryset(self): 
        for post in Post.objects.all():
             return post.event_post.all() #event_post is a related_name of post see models below

#This is incorrect it shows the post 30 times. 10 times for each event. I want to see only 3 posts. They can see the events when they click to open the post

我该如何实现:

我的事件模型。py

class Event(models.Model):
        user = models.ForeignKey(User, related_name='host')
        post = models.ForeignKey(Post, related_name='event_post')
        price = models.DecimalField(max_digits=5, decimal_places=2)
        stock = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(15)])
        initial_stock = models.IntegerField(validators=[MinValueValidator(1), MaxValueValidator(15)], default=1)
        date = models.DateField()
        time_from = models.TimeField()
        time_to = models.TimeField()
        available = models.BooleanField(default=True)
        note = models.CharField(max_length=350, blank=True, null=True)
        created = models.DateTimeField(auto_now_add=True)
        updated = models.DateTimeField(auto_now=True)

我的帖子模型。py

class Post(models.Model):
    user = models.ForeignKey(User, related_name='posts')
    group = models.ForeignKey(Group, related_name='posts')
    created_at = models.DateTimeField(auto_now=True)
    title = models.CharField(max_length=250, unique=True)
    slug = models.SlugField(allow_unicode=True, unique=True)
    message = models.TextField()
    message_html = models.TextField(editable=False)
    post_image = models.ImageField(upload_to='post_images/')

2 个答案:

答案 0 :(得分:1)

您为什么不做Post.objects.all(),然后在模板上显示该帖子的详细信息。然后,当您单击一个。然后,您可以传递selected_post.event_post_set.all()。如果这不能回答您的问题,请告诉我。

编辑:这将起作用,我想您可能有些困惑?仅仅因为您的链接显示事件,并不意味着您必须使用该模型。是的,您应该像PostView那样使用Post模型来返回该视图。这将返回您的3个帖子。然后,当您单击一个时,会将帖子pk传递到新的EventView上,该操作将类似于...

post = Post.objects.get(pk=passed_in_post_pk)
...
return post.event_post_set.all()

检查帖子中是否至少有一个事件。您可以使用一些查询集并在最后打一个.exists(),然后执行一个if语句。

post_events_exist = post.event_post_set.all().exists()
if post_events_exist:
    # there is at least 1 event in the query set.

完整的示例有点伪代码:

views.py

# Rename EventView --> PostView
# Inside of your now PostView
# All we need to do is return all your instances of Post
# and go to your post_template.html (shows the posts, you call it events)
return Post.objects.all()

# Inside of a new view called EventView
# We can get to this view by clicking one of the posts above.
# This assumes we send a parameter through url in template.
# This will send user to event_template.html (shows all events for that post)
post = Post.objects.get(pk=passed_in_post_pk)
return post.post_event_set.all()

post_template.html

<!-- assuming all_posts = Post.objects.all() -->
{% for post in all_posts %}
    {{ post.title }}
    <a href="{{ url_that_links_to_event_view post.pk }}">Info</a>
    <!-- this will send post.pk as a parameter to that view (so long as your accept a parameter in your urls.py for this link -->
{% endfor %}

event_template.html

{% for event in all_events %}
    {{ event.price }}
{% endfor %}

我不使用基于类的视图,因为我认为它们很烂,但是这个伪代码应该足以让您实现它。我使用填充值/变量提供了所需的语法。

答案 1 :(得分:0)

只需稍微修改@OhGreatOne的代码即可满足我的需求

for post in Post.objects.all():
    if post.event_post.exists():
        print.post.title: 

简直不敢相信