Django自定义管理器与过滤参数

10
我希望添加一个自定义管理器,可以从模板中调用,但不会影响整个模型(例如管理员视图),并且监听在请求中设置的参数(user_profile)。
以下是我目前拥有的内容:
models.py:
class CurrentQuerySet(models.query.QuerySet):
    def current(self):
            return self.filter(id=1) ## this simplified filter test works..
class CurrentManager(models.Manager):
    use_for_related_fields = True
    def get_query_set(self):
            return CurrentQuerySet(self.model)
    def current(self, *args, **kwargs):
            return self.get_query_set().current(*args, **kwargs)

模型B的定义如下:

    objects = CurrentManager()

模板调用:
{% for b in a.b_set.current %}

但是一旦我尝试向该过滤器传递参数(在这种情况下,是存储在用户资料中的日期),该方法就不会返回任何结果。

例如:

models.py

class CurrentQuerySet(models.query.QuerySet):
    def current(self,my_date): 
            return self.filter(valid_from__lte=my_date) 

showA.html

{% for b in a.b_set.current(request.user.get_profile.my_date) %}

我尝试在view.py中设置参数,而不是从模板中传递参数。

@login_required
def showA(request,a_id):
    my_date = request.user.get_profile().my_date
    a = A.objects.get(id=a_id)
    t = loader.get_template('myapp/showA.html')
    c = RequestContext(request,{'a':a,'my_date':my_date,})
    return HttpResponse(t.render(c))

我在这里缺少哪一部分(或者是理解错误)?

谢谢

R

编辑

这里是模型。如先前提到的,这个例子中是一个简单的1:n关系,但在其他情况下也可能是m:n关系。

class A(models.Model):
    #objects = CurrentManager()
    a = models.CharField(max_length=200)
    description = models.TextField(null=True,blank=True)
    valid_from = models.DateField('valid from')
    valid_to = models.DateField('valid to',null=True,blank=True)
    def __unicode__(self):
            return self.a

class B(models.Model):
    #objects = models.Manager()
    objects = CurrentManager()
    a = models.ForeignKey(A)
    b = models.CharField(max_length=200)
    screenshot = models.ManyToManyField("Screenshot",through="ScreenshotToB")
    description = models.TextField(null=True,blank=True)
    valid_from = models.DateField('valid from')
    valid_to = models.DateField('valid to',null=True,blank=True)
    def __unicode__(self):
            return self.b

编辑-2

接受的答案至少适用于一个关系。

对于更嵌套的数据模型,这种方法似乎无法产生预期的结果:

models.py

class C(models.Model):
    objects = CurrentManager()
    b = models.ForeignKey(A)
    c = models.CharField(max_length=200)
    description = models.TextField(null=True,blank=True)
    valid_from = models.DateField('valid from')
    valid_to = models.DateField('valid to',null=True,blank=True)
    def __unicode__(self):
            return self.c

views.py

@login_required
def showA(request,a_id):
    a = A.objects.get(id=a_id)
    my_date = request.user.get_profile().my_date
    b_objects = a.b_set.current(my_date)
    c_objects = b_objects.c_set.current(my_date)
    t = loader.get_template('controltool2/showA.html')
    c = RequestContext(request,{'a':a,'b_objects':b_objects,'c_objects':c_objects,})
    return HttpResponse(t.render(c))

这会返回错误:'QuerySet'对象没有属性'c_set'

你能在这里同时包含两个模型以便我们更好地帮助你吗? - carl-lopez
你现在可以在底部找到这些模型了。期待你的反馈,我已经连续一周每晚都在研究这个。 :-) - szeta
看一下我的更新回复,看看是否有助于你重新回到正轨。 - carl-lopez
非常感谢,你的更新回复起作用了(经过一点小修改)。我当然会把你的答案标记为“已接受”。但是这个解决方案似乎只适用于一个 _set。我的真实模型更嵌套(B 有很多 C),在那里似乎不起作用(请参见原始帖子的 edit-2)。 - szeta
1个回答

11

我会简化它:

class CurrentManager(models.Manager):
    def current(self, my_date):
        return super(CurrentManager, self).get_query_set().filter(valid_from__lte=my_date) 

然后像这样使用它:

a = A.objects.get(id=a_id)
my_date = request.user.get_profile().my_date
b_objects = a.b_set.objects.current(my_date)

然后只需将a作为模板的参数传递,并使用以下方式访问过滤后的对象:

{% for b in b_objects %}

希望这可以帮到您!

编辑(由请求者提出):

我必须按照以下方式进行调整才能使其正常工作:

a = A.objects.get(id=a_id)
my_date = request.user.get_profile().my_date
b_objects = a.b_set.current(my_date)

出现了错误:"'RelatedManager' 对象没有属性 'objects'"

a.b_set.objects.current(my_date)

嗨,感谢您的简化。也许我应该更清楚地说明,这里涉及到两个模型,模型A和模型B(在这种情况下是1:n)。这就是为什么我要执行 a = A.objects.get(id=a_id) 然后 {% for b in a.b_set.current %}。我该如何应用它?目前在视图中,我只涉及到了A。 - szeta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接