处理Django中的相关模型以用于Django-Piston

时间:2010-09-16 18:44:47

标签: django django-piston

我的设置是这样的(为简单而改变)

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和category。

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

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

然而,这是为django-piston生成的,如果你返回一个QuerySet对象,它似乎最开心(特别是如果你定义自己的字段!)。

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

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

  1. 有没有办法过滤或以某种方式限制记录的子记录(即每个documents的过滤器author.documents
  2. 如果没有,这样做的功能方法是什么,也适用于django-piston?
  3. 是否有一些更容易,更好的方法来做我正在尝试做的事情(如果没有给出id,则显示所有作者没有他们的文件,但如果只过滤给一位作者则显示子记录?)
  4. 澄清

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

    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的内容。看起来这应该是可能的,但也许不是吗?

1 个答案:

答案 0 :(得分: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 aggregation and annotation或者可能使用它使用从作者到文档的left join的原始sql。




在澄清问题后编辑:

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