试图将表单从generic.FormView传递给generic.DetailView

时间:2018-12-04 13:08:21

标签: python django

我是Django的新手,它只是对进一步模型的测试。我试图将表单从generic.FormView传递给generic.DetailView,并将插入在先前的HTML(与FormView关联)中的数据展示给另一个HTML(与DetailView关联)。我认为view.py和urls.py之间的链接可能有问题。代码是:

views.py:

class IndexView(generic.FormView):
    template_name = 'dutos/index.html'
    form_class = GetDate
    success_url = 'dutos/detail.html'

    #def form_valid(self, form):                                   
       #return HttpResponse(self.success_url)
       #return super.form_valid(form)

class DetailView(generic.DetailView):
    model = Dutos
    template_name = 'dutos/detail.html'

forms.py

class GetDate(forms.Form):
    dateDataInicial = forms.DateTimeField(label='dataInicial', initial=datetime.now().strftime("%d/%m/%Y %H:%M:%S"), required=False)
    dateDataFinal = forms.DateTimeField(label='dataFinal', initial=datetime.now().strftime("%d/%m/%Y %H:%M:%S"), required=False)

urls.py:

from django.urls import path
from .views import views

urlpatterns = [
    path('', views.IndexView.as_view(), name="index"),
    path('detail/', views.DetailView.as_view(), name="detail"),
]

index.html:

<!DOCTYPE html>
<html>
<head>
<title>Template</title>
</head>
<body>
<h1>Teste HTML</h1>
<div class="container-fluid" id="wrapper">
    <div class="row">
        <form action="/detail/" method="post">
            {% csrf_token %}
            {{ form.non_field_errors }}
            <div>
                <div class="fieldWrapper">
                    {{ form.dateDataInicial.errors }}
                    <label for="{{ form.dateDataInicial }} Data Inicial: </label>
                    {{ form.dateDataInicial }}
                </div>
                <div class="fieldWrapper">
                    {{ form.dateDataFinal.errors }}
                    <label for="{{ form.dateDataFinal }} Data Final: </label>
                    {{ form.dateDataFinal }}
                </div>
            <input type="submit" value="Pesquisar">
            </div>
        </form>
    </div>
</div>
</body>
</html>

detail.html:

<!DOCTYPE html>
<html>
<head>
<title>Template</title>
</head>
<body>

<h1>Template HTML</h1>
{{form.cleaned_data['dateDataInicial']}}
{{form.cleaned_data['dateDataFinal']}}

</body>
</html>

我已经将“ {{form.cleaned_data ['dateDataInicial']}}”更改为“ form.dateDataInicial”,或者只是清除了所有内容并放入“ Test”以显示简单的HTML。我收到HTTP错误405。

2 个答案:

答案 0 :(得分:1)

您发布的代码确实存在很多错误。

您得到405,因为索引模板中的表单尝试直接发布到详细URL,该URL未设置为接受POST请求。这样做的另一个问题是将不对表单进行验证,因为验证应该在IndexView中进行,而不是在DetailView中进行。另外,DetailView对表单一无所知,因此form.cleaned_data在模板上下文中将不存在;并且,Django模板语法不支持通过方括号查找字典,因此{{ form.cleaned_data['dateDataInicial'] }}不起作用。

为了使验证生效,您需要将表单提交回IndexView,然后将其重定向到详细信息视图。 (代码的另一个问题是success_url应该是URL,而不是模板路径。)然后,问题就变成了如何从一个视图获取数据到另一个视图。会议是实现此目标的好方法。所以:

class IndexView(generic.FormView):
    template_name = 'dutos/index.html'
    form_class = GetDate
    success_url = reverse_lazy('detail')

    def form_valid(self, form):                                   
       self.request.session['dates'] = form.cleaned_data
       return super.form_valid(form)

更改index.html中的表单标签:

 <form action="" method="post">

详细视图:

class DetailView(generic.DetailView):
    model = Dutos
    template_name = 'dutos/detail.html'

    def get_context_data(self, **kwargs):
        kwargs['dates'] = self.request.session.pop('dates', {})
        return super().get_context_data(**kwargs)

和detail.html:

{{ dates.dateDataInicial }}
{{ dates.dateDataFinal }}

答案 1 :(得分:0)

借助Daniel和他的代码的帮助,我找出了导致我需要的修改。我已经将DetailView的genericView从“ generic.DetailView”更改为“ generic.ListView”。完成后,出现了另一个问题。要通过JSON传递“ datetime”,它将转换为字符串格式,并且所有日期都被视为字符串,因此我无法在detail.html中的单独字段中显示两个日期。为了解决这个问题,我将针对Daniel提出的解决方案进行了调整,并将该字段分为两部分,以便可以通过form.cleaned_data获得并将其转换为字符串,现在,我无需担心JSON序列化“ datetime” 。

views.py:

class IndexView(generic.FormView):
    template_name = 'dutos/index.html'
    form_class = GetDate
    success_url = reverse_lazy('detail')

    def form_valid(self, form):
        #self.request.session['dates'] = json.dumps(form.cleaned_data, cls=DjangoJSONEncoder)
        self.request.session['dateInicial'] = str(form.cleaned_data['dateDataInicial'])
        self.request.session['dateFinal'] = str(form.cleaned_data['dateDataFinal'])
        return super().form_valid(form)

class DetailView(generic.ListView):
    model = Dutos
    template_name = 'dutos/detail.html'

    def get_context_data(self, **kwargs):
        #kwargs['dates'] = self.request.session.pop('dates', {})
        kwargs['dateInicial'] = self.request.session.pop('dateInicial', {})
        kwargs['dateFinal'] = self.request.session.pop('dateFinal', {})
        return super().get_context_data(**kwargs)

index.html:

<div class="container-fluid" id="wrapper">
    <div class="row">
        <form action="" method="post">
            {% csrf_token %}
            {{ form.non_field_errors }}
            <div>
                <div class="fieldWrapper">
                    {{ form.dateDataInicial.errors }}
                    <label for="{{ form.dateDataInicial }} Data Inicial: </label>
                    {{ form.dateDataInicial }}
                </div>
                <div class="fieldWrapper">
                    {{ form.dateDataFinal.errors }}
                    <label for="{{ form.dateDataFinal }} Data Final: </label>
                    {{ form.dateDataFinal }}
                </div>
            <input type="submit" value="Pesquisar">
            </div>
        </form>
    </div>
</div>

detail.html:

<body>

<h1>Detalhes</h1>

{{ dateFinal }}
<br>
{{ dateInicial }}

</body>