2

我有这样的设置(为简单起见进行了更改)

class Author(models.Model)
    name = models.CharField(max_length=100)
    ...

class Document(models.Model):
    title = models.CharField(max_length=200)
    content - models.TextField()
    author = models.ForeignKey("Author", related_name="documents")
    date_published = models.DateTimeField()
    categories = models.ManyToManyField("Category")

class Category(models.Model):
    name = models.CharField(max_length=100)

我正在提取作者记录,但我只想为每个符合特定标准的作者提取相关文档记录——比如 date_published 和类别。

我知道做到这一点的简单方法是使用 将记录作为字典列表拉入Author.objects.values(),遍历每条记录并运行:

author['documents']=Document.objects.filter(categories__in=[category_list], date_published__year=year)`

但是,这是为 django-piston 生成的,如果您返回 QuerySet 对象,它似乎是最快乐的(特别是如果您正在定义自己的字段!)。

部分原因可能是因为我对基础 django-piston 代码进行了更改。基本上,此处代码的当前版本会覆盖该fields值。我更改了此代码,以便可以fields根据请求更改 Handler 的值(因此,如果请求是针对特定资源的,我可以提供更多详细信息)。

所以我想我的问题是三个方面:

  1. 有没有办法过滤或以某种方式限制记录的子记录(即过滤documents每个author.documents
  2. 如果不是,那么在 django-piston 上也可以使用的功能性方法是什么?
  3. 是否有一些更简单、更好的方法来做我想做的事情(如果没有给出 id,则显示所有作者没有他们的文档,但如果只过滤给一个作者,则显示子记录)?

澄清

好的,为了清楚起见,这是我想要的伪代码:

def perhaps_impossible_view(request, categories=None, year=None):
    authors = Author.objects.all()
    authors.something_magical_happens_to_documents(category__in=[categories], date_published__year=year)
    return render_to_response('blar.html', locals(), RequestContext(request))

因此,如果我其放入模板中,则无需任何修改即可工作:

{% for a in authors %}
    {% for d in authors.documents.all %}
        {{ d.title }} is almost certainly in one of these categories: {{ categories }} and was absolutely published in {{ year }}. If not, .something_magical_happens_to_documents didn't work.
    {% endfor %}
{% endfor %}

something_magical_happens_to_documents必须运行并实际更改documents每个作者记录的内容。看起来这应该是可能的,但也许不是?

4

1 回答 1

0

编辑...或更好...替换!:)

确实,没有文档匹配的作者不会在查询集中,因此您必须在之后将它们添加回来(我找不到更好的方法,但也许有人知道如何在不使用原始 sql 的情况下不删除它们)。

您可以获得作者的完整文档计数,因为您不使用查询集来获取文档计数:

qryset = Author.objects.all()
qryset = qryset.filter(documents__categories__name__in = category_list).distinct()
qryset = qryset.filter(documents__date_published__year=year)

print(qryset)给出[<Author: Author object>](如果只有 1 个作者匹配所有类别)并且qryset[0].documents.count()只返回匹配的文档数量(不是作者的所有文档 - 在我测试的情况下为 2 个,作者有 4 个但只有 2 个匹配所有条件)。

如果您在上述步骤中使用 dict (.values()) 而不是查询集,则不能这样做(我认为),因为 dict 没有文档字段,所以:

qryset_dict = Author.objects.values()
qryset_dict = qryset_dict.filter(documents__categories__name__in = category_list).distinct().values()
qryset_dict = qryset_dict.filter(documents__date_published__year=year).values()

当您发出时,qryset_dict[0].documents.count()您会收到一个错误:

AttributeError: 'dict' object has no attribute 'documents'


现在要添加过滤后的作者,您可以执行以下操作:

res = []
for a in Author.objects.all():
    if a in qryset:
        res.append([a,a.documents.count()])
    else:
        res.append([a,0])

res 将是第 1 列中的列表,<authors>第 2 列中匹配的文档数。

我知道这远非完美......但如果您只对count()每个作者的匹配文档感兴趣,我认为您可以找到使用django 聚合和注释的更好方法,或者可能使用原始 sql 使用left join从作者到文档.




问题澄清后编辑:

def possible_view(request, categories=None, year=None):
    # you will pass these as parmeters of course
    category_list = ['c2', 'c3']
    year = 2010

    qryset = Document.objects.filter(categories__name__in = category_list).distinct()
    qryset = qryset.filter(date_published__year=year)
    authors = Author.objects.all()
    return render_to_response('blar.html', { 'result': qryset, 'authors': authors, 'categories': category_list, 'year': year }, RequestContext(request))

模板blar.html

{% for a in authors %}
    <b>{{a.name}}</b><br />
    {% for d in result %}
        {% if d.author.name == a.name %}
            {{ d.title }} is almost certainly in one of these categories: {{ categories }} and was absolutely published in {{ year }}. If not, .something_magical_happens_to_documents didn't work.<br />
        {% endif %}
    {% endfor %}<br />
{% endfor %}

这将为您提供一些不是很漂亮的东西,但是对于所有作者以及在每个作者下方,他们的文档列表都属于category_list(OR 条件,对于 AND,您需要过滤每个类别的查询而不是使用__in)。

如果作者在 中没有文档category_list,则将在其下方无文档列出。


就像是:

aut1
tit2 is almost certainly in one of these categories: ['c2', 'c3'] and was absolutely   published in 2010. If not, .something_magical_happens_to_documents didn't work.
tit1 is almost certainly in one of these categories: ['c2', 'c3'] and was absolutely published in 2010. If not, .something_magical_happens_to_documents didn't work.

aut2
tit3 is almost certainly in one of these categories: ['c2', 'c3'] and was absolutely published in 2010. If not, .something_magical_happens_to_documents didn't work.

aut3
于 2010-09-17T23:19:07.770 回答