允许用户选择随机博客

时间:2018-01-08 18:23:30

标签: python django url random view

我已经开始使用Django 2.0和Python 3.6.3开发一个网站,该网站将显示自定义的“帖子”,如博客文章。

我希望用户能够点击基本上显示“随机发布”的按钮。此按钮会将它们带到一个模板,该模板会加载随机博客文章。

这是我的帖子模型:

class Post(models.Model):
    post_id = models.AutoField(primary_key=True)
    ... other fields
    ... other fields

    def publish(self):
        self.published_date = timezone.now()
        self.save()

    def __str__(self):
        return self.title     

以下是一些相关观点:

class PostListView(ListView):
    model = Post
    template_name = 'blog/post_list.html'

class PostDetailView(DetailView):
    model = Post
    template_name = 'blog/post_detail.html'

这是我有问题的观点:

import random

def random_post(request):
    post_ids = Post.objects.all().values_list('post_id', flat=True) 
    random_obj = Post.objects.get(post_id=random.choice(post_ids))
    context = {'random_post': random_obj,}
    return render(request, 'blog/random_post.html', context)

这里我试图为Post模型创建所有post_id值的值列表。然后我试图从这个值列表中随机选择,这将是一个随机ID。然后我尝试使用这个逻辑创建一个上下文并渲染一个模板。

以下是相关的urlpatterns:

urlpatterns = [
    path('post/<int:pk>/', 
        views.PostDetailView.as_view(),name='post_detail'),
    path('post/random/<int:pk>', views.random_post, name='random_post'),

毋庸置疑,这不起作用。

如果我放弃“int:pk”,它会呈现一个没有数据的空白模板 - 没有博客帖子。如果我包含,它会导致错误 - 找不到参数。我假设视图中没有查询数据,或者数据没有从视图正确发送到模板。

我是Django的新手。感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

对于您想要的行为,您的网址应为:

urlpatterns = [
    path('post/random/', views.random_post, name='random_post'),
    path('post/<int:pk>/', 
        views.PostDetailView.as_view(),name='post_detail'),
]

你的random_post视图是:

def random_post(request):
    post_count = Post.objects.all().count()
    random_val = random.randint(1, post_count-1)
    post_id = Post.objects.values_list('post_id', flat=True)[random_val]
    return redirect('post_detail', pk=post_id)

这会产生两个查询 - 一个用于获取所有帖子的计数,另一个用于获取随机位置的帖子ID。这样做的原因是,您不必从数据库中获取所有ID - 如果您有数千个帖子,那将非常低效。

答案 1 :(得分:0)

这是有效的观点。

def random_post(request):
    post_count = Post.objects.all().count()  
    random_val = random.randint(0, post_count-1)  
    post_id = Post.objects.values_list('post_id', flat=True)[random_val]   
    return redirect('post_detail', pk=post_id) #Redirect to post detail view