【问题标题】:Complex forms with Django使用 Django 的复杂表单
【发布时间】:2012-09-18 15:54:47
【问题描述】:

考虑以下调查问题:

你喜欢这个问题吗? (选择一项)

  • 是的
  • 不,因为
    • 我不喜欢它的格式
    • 我不喜欢这个措辞
    • 其他原因:........
  • 其他回复(请注明)......................

我试图代表一系列问题,其中一些是这样的。有些更简单(只是一个选择列表)。但是我在尝试用 Django 和它自己的表单方式来解决这个问题时遇到了一些问题。我们有以下问题:

  • 我们需要服务器端验证。只能指定一个选项。在上述“其他”选项的情况下,需要一个后续字符域。

  • 我们需要在选项中添加一个字符域!我很确定我可以通过模板破解这些内容,但请记住这一点。

  • 为了使事情复杂化,问题及其答案需要可编辑。我已经使用 YAML 完成了这项工作,并且可以生成表单,效果很好。

那么破解 Django 表单系统以允许我这样做的最佳方法是什么?我应该完全打扰django.forms,还是只写一些以自己的方式完成所有事情的东西? 会怎么做呢?

【问题讨论】:

    标签: django django-forms


    【解决方案1】:

    如果你想避免处理表单,我建议使用 jquery 的 $.ajax() 方法。基本上,您只需要创建一个空白表单模型来捕获 POST,然后您就可以获取数据并按照您的意愿使用它。这是一个例子:

    #models.py
    class BlankForm(forms.Form):    
    
        def __unicode__(self):
            return "BlankForm"
    
    #views.py
    def my_view(request):
    
        if request.method == 'POST':
            if 'answer' in request.POST:
                form = BlankForm(request.POST)
    
                if form.is_valid():
                    foo = request.POST.__getitem__('add')
                    bar = request.POST.__getitem__('bar')
                    baz = request.POST.__getitem__('baz')
                    #Do stuff with your data:
                    return HttpResponse('ok')
    

    然后在你的网页中你可以这样:

    <script type="text/javascript">
    
            function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie != '') {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = jQuery.trim(cookies[i]);
                        // Does this cookie string begin with the name we want?
                        if (cookie.substring(0, name.length + 1) == (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                            break;
                        }
                    }
                }
                return cookieValue;
            }
    
            function csrfSafeMethod(method) {
                // these HTTP methods do not require CSRF protection
                return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
    
            var csrftoken = getCookie('csrftoken');
    
            $.ajaxSetup({
                crossDomain: false, // obviates need for sameOrigin test
                    beforeSend: function(xhr, settings) {
                        if (!csrfSafeMethod(settings.type)) {
                        xhr.setRequestHeader("X-CSRFToken", csrftoken);
                    }
                }
            });
    
            $.ajax({
                type: 'POST',
                data: {
                    'answer': true,
                    'foo': foo,
                    'bar': bar,
                    'baz': baz
                },
                dataType: 'application/json'
            });
        }
    
    </script>
    

    所有关于 cookie 和 CSRF 令牌的东西都与 django 的 CSRF 保护系统有关。基本上,您需要担心的只是编辑 $.ajax() 方法中的 Data 字段

    【讨论】:

      【解决方案2】:

      各种选项将是一个ForeignKey 指向另一个包含响应的表。您必须在该 FK 中有多个字段来保存主要答案和子答案,并且您必须适当地重新组合(或重新排序,如果您需要明确的顺序)。您还需要CharField 才能保留“其他”响应。将这两个字段封装在自定义字段中并使用自定义小部件在表单中显示控件可能是最简单的方法。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-02-10
        • 2015-06-30
        • 1970-01-01
        • 1970-01-01
        • 2019-09-02
        • 2011-06-17
        • 2014-10-14
        • 1970-01-01
        相关资源
        最近更新 更多