使用 django-disqus 按回复编号订购食谱查询集
Order a recipe queryset by replies number using django-disqus
我有一个 recipe
型号:
class Recipe(models.Model):
title = models.CharField(_("Recipe Title"), max_length=250)
slug = models.SlugField(_('slug'), unique=True)
author = models.ForeignKey(User, verbose_name=_('user'))
...
我需要为大多数评论的食谱创建一个视图,我正在使用 django-disqus
来处理食谱的评论,但我不知道如何通过食谱的评论编号来排序查询集。
class PopRecipeListView(GlobalQueryMixin, ListView):
model = Recipe
context_object_name = "recipe_list"
template_name = 'recipe/recipe_top_list.html'
def get_queryset(self):
qs = super(PopRecipeListView, self).get_queryset()
if qs:
qs = qs.extra(
select={
'comments': # get comment numbers
}
).filter(shared=True).order_by('-rate')[:20]
return qs
我在文档中找到了这个:https://disqus.com/api/docs/forums/listThreads/
我可以获得一个包含站点和论坛 ID 的 json
文件并遍历它们以获得正确的密钥,但我认为这并不容易。
更深入地寻找,我可以使用如下方式获取 json
文件:
var url = "https://disqus.com/api/3.0/forums/listThreads.json?api_key=" + api_key + "&forum=" + forum; //+ "&limit=100";
,但我不确定。
好的,我有下一个获取参数的函数:
def get_comments_by_site():
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&limit=100'.format(api_key, forum)
raw = requests.get(url)
dict = json.loads(raw)
values = {}
for thread in dict['response']:
item = {thread['slug']: thread['posts']}
values.update(item)
return values
def get_comments_number(slug):
return values[slug]
我创建了两个不同的函数,因为我希望 View
一次获取所有值,然后在 query
中调用 secong 函数从获得的字典中获取值。
我创建了一个mixin
来整合这两个功能:
class DisqusCommentsNumber(object):
values = {}
def get_comments_by_site(self):
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&limit=100'.format(api_key,
forum)
raw = requests.get(url)
dict = json.loads(raw)
for thread in dict['response']:
item = {thread['slug']: thread['posts']}
self.values.update(item)
return self.values
def get_comments_number(self, slug):
return self.values[slug]
我在这里使用 annotate
:
def get_queryset(self):
qs = super(PopRecipeListView, self).get_queryset()
if qs:
qs = qs.annotate(num_comments=get_comments_number('slug')).filter(shared=True).order_by('-num_comments')
return qs
我用 extra
替换了 annotate
并且:
def get_queryset(自我):
qs = super(PopRecipeListView, self).get_queryset()
if qs:
qs = qs.extra(
select={
'num_comments': '{0}'.format(
self.get_comments_number(Recipe.slug)
)
}
).filter(shared=True).order_by('-num_comments')
return qs
现在我得到这个错误:
KeyError at /recipe/popular/
<django.db.models.query_utils.DeferredAttribute object at 0x7f90048f7470>
我认为 mixin
有问题。
我更新了获取 dispatch
函数中所有值的视图,但我收到此错误:
KeyError at /recipe/popular/
<django.db.models.query_utils.DeferredAttribute object at 0x7f6ffebfa4e0>
代码here.
我正在测试其他方法:
我做了一个函数来获取这个值,因为模型是 属性:
@property
def get_comments_number(self):
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&thread:ident={2}'.format(
api_key,
forum,
self.slug
)
raw = requests.get(url)
thread = json.loads(raw.content)
return thread['response'][0]['posts']
有了这个和一个新的字段排序会更容易,但是,我如何使用这个函数来获取值并保存在数据库中?
哪个是这项任务的最佳方法?
谢谢。
尝试 .annotate()
然后按这个新注释的属性排序。
看这里:https://docs.djangoproject.com/en/2.0/ref/models/querysets/#annotate
最后我改变了方法:
我在我的 recipe
模型中创建了一个新函数 属性:
@property
def get_comments_number(self):
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&thread:ident={2}'.format(
api_key,
forum,
self.slug
)
raw = requests.get(url)
thread = json.loads(raw.content)
return thread['response'][0]['posts']
之后,我在模型中添加了一个新字段以保存 comment's number
值。
最后,我在 DetailView
中调用 属性 以更新评论的编号:
def dispatch(self, request, *args, **kwargs):
# TODO: maybe it is necessary create a task for update this in other cases
r = self.get_object()
r.comments = r.get_comments_number
r.save()
# check if the recipe is a private recipe if so through a 404 error
if r.shared == False and self.object.author != request.user:
output = _("Recipe {0} is marked Private").format(self.get_object().slug)
raise Http404(output)
else:
return super(RecipeDetailView, self).dispatch(request, *args, **kwargs)
现在我可以在另一个视图中按评论编号进行过滤:
qs = qs.filter(shared=True).order_by('-comments')
这就是全部。
我有一个 recipe
型号:
class Recipe(models.Model):
title = models.CharField(_("Recipe Title"), max_length=250)
slug = models.SlugField(_('slug'), unique=True)
author = models.ForeignKey(User, verbose_name=_('user'))
...
我需要为大多数评论的食谱创建一个视图,我正在使用 django-disqus
来处理食谱的评论,但我不知道如何通过食谱的评论编号来排序查询集。
class PopRecipeListView(GlobalQueryMixin, ListView):
model = Recipe
context_object_name = "recipe_list"
template_name = 'recipe/recipe_top_list.html'
def get_queryset(self):
qs = super(PopRecipeListView, self).get_queryset()
if qs:
qs = qs.extra(
select={
'comments': # get comment numbers
}
).filter(shared=True).order_by('-rate')[:20]
return qs
我在文档中找到了这个:https://disqus.com/api/docs/forums/listThreads/
我可以获得一个包含站点和论坛 ID 的 json
文件并遍历它们以获得正确的密钥,但我认为这并不容易。
更深入地寻找,我可以使用如下方式获取 json
文件:
var url = "https://disqus.com/api/3.0/forums/listThreads.json?api_key=" + api_key + "&forum=" + forum; //+ "&limit=100";
,但我不确定。
好的,我有下一个获取参数的函数:
def get_comments_by_site():
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&limit=100'.format(api_key, forum)
raw = requests.get(url)
dict = json.loads(raw)
values = {}
for thread in dict['response']:
item = {thread['slug']: thread['posts']}
values.update(item)
return values
def get_comments_number(slug):
return values[slug]
我创建了两个不同的函数,因为我希望 View
一次获取所有值,然后在 query
中调用 secong 函数从获得的字典中获取值。
我创建了一个mixin
来整合这两个功能:
class DisqusCommentsNumber(object):
values = {}
def get_comments_by_site(self):
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&limit=100'.format(api_key,
forum)
raw = requests.get(url)
dict = json.loads(raw)
for thread in dict['response']:
item = {thread['slug']: thread['posts']}
self.values.update(item)
return self.values
def get_comments_number(self, slug):
return self.values[slug]
我在这里使用 annotate
:
def get_queryset(self):
qs = super(PopRecipeListView, self).get_queryset()
if qs:
qs = qs.annotate(num_comments=get_comments_number('slug')).filter(shared=True).order_by('-num_comments')
return qs
我用 extra
替换了 annotate
并且:
def get_queryset(自我): qs = super(PopRecipeListView, self).get_queryset()
if qs:
qs = qs.extra(
select={
'num_comments': '{0}'.format(
self.get_comments_number(Recipe.slug)
)
}
).filter(shared=True).order_by('-num_comments')
return qs
现在我得到这个错误:
KeyError at /recipe/popular/
<django.db.models.query_utils.DeferredAttribute object at 0x7f90048f7470>
我认为 mixin
有问题。
我更新了获取 dispatch
函数中所有值的视图,但我收到此错误:
KeyError at /recipe/popular/
<django.db.models.query_utils.DeferredAttribute object at 0x7f6ffebfa4e0>
代码here.
我正在测试其他方法: 我做了一个函数来获取这个值,因为模型是 属性:
@property
def get_comments_number(self):
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&thread:ident={2}'.format(
api_key,
forum,
self.slug
)
raw = requests.get(url)
thread = json.loads(raw.content)
return thread['response'][0]['posts']
有了这个和一个新的字段排序会更容易,但是,我如何使用这个函数来获取值并保存在数据库中? 哪个是这项任务的最佳方法?
谢谢。
尝试 .annotate()
然后按这个新注释的属性排序。
看这里:https://docs.djangoproject.com/en/2.0/ref/models/querysets/#annotate
最后我改变了方法:
我在我的 recipe
模型中创建了一个新函数 属性:
@property
def get_comments_number(self):
api_key = settings.DISQUS_API_KEY
forum = settings.DISQUS_WEBSITE_SHORTNAME
url = 'https://disqus.com/api/3.0/forums/listThreads.json?api_key={0}&forum={1}&thread:ident={2}'.format(
api_key,
forum,
self.slug
)
raw = requests.get(url)
thread = json.loads(raw.content)
return thread['response'][0]['posts']
之后,我在模型中添加了一个新字段以保存 comment's number
值。
最后,我在 DetailView
中调用 属性 以更新评论的编号:
def dispatch(self, request, *args, **kwargs):
# TODO: maybe it is necessary create a task for update this in other cases
r = self.get_object()
r.comments = r.get_comments_number
r.save()
# check if the recipe is a private recipe if so through a 404 error
if r.shared == False and self.object.author != request.user:
output = _("Recipe {0} is marked Private").format(self.get_object().slug)
raise Http404(output)
else:
return super(RecipeDetailView, self).dispatch(request, *args, **kwargs)
现在我可以在另一个视图中按评论编号进行过滤:
qs = qs.filter(shared=True).order_by('-comments')
这就是全部。