django:根据条件排除某些表单元素 [英] django: exclude certain form elements based on a condition

查看:98
本文介绍了django:根据条件排除某些表单元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些表单字段,我想根据是否满足某个条件来包含/排除。我知道如何包含和排除表单元素,但是当我希望元素根据函数的结果显示时,我很难做到。

I have some form fields that I want to include/exclude based on whether or not a certain condition is met. I know how to include and exclude form elements, but I am having difficulty doing it when I want it elements to show based on the outcome of a function.

这是我的形式:

class ProfileForm(ModelForm):
    # this_team = get Team instance from team.id passed in
    # how?

    def draft_unlocked(self):
        teams = Team.objects.order_by('total_points')
        count = 0
        for team in teams:
            if team.pk == this_team.pk:
                break
            count += 1

        now = datetime.datetime.now().weekday()
        if now >= count:
            # show driver_one, driver_two, driver_three
        else:
            # do not show driver_one, driver_two, driver_three

class Meta:
    model = Team

我要完成的是根据总分的积分,一个团队在指定的日子之前不应该改变他们的司机。在最后一个队伍中,星期一可以添加/删除一名司机,第二到最后一个队伍可以在星期二添加/删除,等等...

What I am trying to accomplish is, based on the standings of total points, a team should not be able to change their driver until their specified day. As in, the last team in the standings can add/drop a driver on Monday, second to last team can add/drop on Tuesday, and so on...

所以第一个问题 - 如何从传入的id中将Team实例从表单本身中取得。而且,如何根据draft_unlocked()的结果来包含/排除。

So the first problem -- how do I get the Team instance inside the form itself from the id that was passed in. And, how do I include/exclude based on the result of draft_unlocked().

或者还有更好的方法来做所有这些?

Or perhaps there is a better way to do all of this?

非常感谢大家。

推荐答案

这实际上很简单(条件字段设置) - 这里有一个简单的例子:

This is actually fairly straightforward (conditional field settings) - here's a quick example:

from django.forms import Modelform
from django.forms.widgets import HiddenInput

class SomeForm(ModelForm):

    def __init__(self, *args, **kwargs):
        # call constructor to set up the fields. If you don't do this 
        # first you can't modify fields.
        super(SomeForm, self).__init__(*args, **kwargs)

        try:
            # make somefunc return something True
            # if you can change the driver.
            # might make sense in a model?
            canchangedriver = self.instance.somefunc()                          
        except AttributeError:
            # unbound form, what do you want to do here?
            canchangedriver = True # for example?

        # if the driver can't be changed, use a input=hidden
        # input field.
        if not canchangedriver:
            self.fields["Drivers"].widget = HiddenInput()

    class Meta:
        model = SomeModel

所以,要点:


  • self.instance 表示绑定对象,如果表单被绑定。我相信它作为一个命名参数传递,因此在 kwargs 中,父构造函数用于创建 self.instance

  • 您可以在调用父构造函数后修改字段属性。

  • 窗口小部件是如何显示表单的。 HiddenInput基本上意味着< input type =hidden... />

  • self.instance represents the bound object, if the form is bound. I believe it is passed in as a named argument, therefore in kwargs, which the parent constructor uses to create self.instance.
  • You can modify the field properties after you've called the parent constructor.
  • widgets are how forms are displayed. HiddenInput basically means <input type="hidden" .../>.

有一个限制;如果我修改提交的POST / GET数据,我可以篡改输入来更改值。如果你不想这样做,需要考虑的是覆盖窗体的验证(clean())方法。请记住,Django中的所有内容都只是对象,这意味着您可以实际修改类对象,并随意添加数据(不会持久化)。所以在你的 __ init __ 你可以:

There is one limitation; I can tamper with the input to change a value if I modify the submitted POST/GET data. If you don't want this to happen, something to consider is overriding the form's validation (clean()) method. Remember, everything in Django is just objects, which means you can actually modify class objects and add data to them at random (it won't be persisted though). So in your __init__ you could:

self.instance.olddrivers = instance.drivers.all()

然后在您的干净的方法表示:

Then in your clean method for said form:

def clean(self):
    # validate parent. Do this first because this method
    # will transform field values into model field values.
    # i.e. instance will reflect the form changes.
    super(SomeForm, self).clean()

    # can we modify drivers?
    canchangedriver = self.instance.somefunc() 

    # either we can change the driver, or if not, we require 
    # that the two lists are, when sorted, equal (to allow for 
    # potential non equal ordering of identical elements).

    # Wrapped code here for niceness
    if (canchangedriver or 
                   (sorted(self.instance.drivers.all()) == 
                    sorted(self.instance.olddrivers))):  
        return True
    else:
        raise ValidationError() # customise this to your liking.

这篇关于django:根据条件排除某些表单元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆