1

我只是好奇 Django 自动生成具有灵活参数名称的方法的方式,比如c = p.choice_set.filter(choice_startswith = 'Just hacking') 你能解释一下它是如何完成的吗?

这是示例的代码

 import datetime
from django.db import models
from django.utils import timezone

class Poll(models.Model):
    question = models.CharField(max_length = 200)
    pub_date = models.DateTimeField('date published')
    def was_published_recently(self):
        return self.pub_date >= timezone.now() - datetime.timedelta(days = 1)

    def __unicode__(self):
        return self.question

class Choice(models.Model):
    poll = models.ForeignKey(Poll)
    choice = models.CharField(max_length = 200)
    votes = models.IntegerField()
    def __unicode__(self):
        return self.choice
4

3 回答 3

3

这是通过分析函数的关键字参数按字段名称和条件拆分它们来完成的。对概念验证进行一些简化,如下所示:

def filter(**kwargs):
    for i in kwargs:
        field, condition = i.split('__')
        print field, condition

>>> filter(choice__startswith='prefix-')
choice startswith

然后使用字段名称和条件对真实对象执行某些操作。

于 2012-08-13T20:25:12.143 回答
1

我假设您在示例中谈论的是choice_startswith 参数。本质上,这是通过利用 python 对关键字参数的处理来实现的。这是非常简单的魔法,我会在这里告诉你。

本质上,您定义了一个方法或函数,其签名类似于::

def somefunc(*args, **kwargs):
    print args
    print kwargs

正如你在这里看到的,我们定义了看起来很奇怪的参数。然而,这些不是正常的论点。args 前面的*表示任何非关键字参数都将args作为元组存储在变量中。kwargs**前面的表示任何关键字参数都将 kwargs作为字典存储在变量中。

所以如果你像这样运行这个函数:

>>> somefunc('a', 'b', alpha='alpha', beta='beta')

你会得到这个输出:

>>> ('a', 'b')
>>> {'alpha': 'alpha', 'beta': 'beta'}

您可以分别将 args 和 kwargs 操作为元组或字典。如果你分析这些,你可以做 django 用 filter 方法做的事情。

于 2012-08-13T20:26:47.480 回答
0

ForeignRelatedObjectsDescriptor 类在相关字段中提供了像 objectname_set 或 related_name 这样的管理器

见: https ://github.com/django/django/blob/master/django/db/models/fields/related.py#L433

于 2012-08-13T20:41:20.367 回答