首页 > 解决方案 > django,直接查看另一个 html 页面

问题描述

我正在使用 Django 开发网站。该网站旨在用于搜索存储在 MySQL 数据库中的信息。

这是当前网站的基本流程。1) index.html - 这有一个表单来选择一个选项 2) 根据选项,用户将重定向到 search.html (包括一个表单) 3) 一旦用户提供条件,结果将显示在 reply.html

在我的 views.py 中,我有两个功能。

from django.shortcuts import render
from website.models import WebsiteRepository
from .forms import SearchForm
from .forms import SelectTypeForm


def Search(request):
if request.method == 'POST':
    #do something
    return render(request, 'reply.html', {'env_dict':env_dict})
else:
    #do something
    return render(request, 'search.html', context = context)

def index(request):

if request.method =='POST':
   #do something
   return render(request, 'search.html', context = context) 
else:
    #do something
    return render(request, 'index.html', context= context)  

当我进入 index.html 页面时,我可以选择一个选项,它会引导我进入 search.html。之后,我在那里填写表格并提交,它不会给我 reply.html 页面。

我有一种感觉,我可以通过更改 urls.py 来完成这项工作。

from django.urls import path
from website import views


 urlpatterns = [
      path('', views.index, name='index'),
      #path('search/', view.Search, name ='Search')

 ]

我试着用谷歌搜索它。但是它的细节太多了,我有点迷失了。

你们中的任何人都知道如何实现这一目标吗?

谢谢

搜索.html

{% extends "base_generic.html" %}
{% block content %}

   <h3>Welcome to search information Repository</h3>
   <form method="post">
   {% csrf_token %}
   {{form.as_p}}
   <button type = 'submit'>submit</button>
   </form>

{% endblock %} 

索引.html

{% block content %}
   <h3>Welcome to information Repository</h3>
       <form method="post">
       {% csrf_token %}
       {{form.as_p}}
    <button type = 'submit'>submit</button>
  </form>

只是为了更清楚地说明问题,我也添加了 forms.py

from django import forms
from .models import  WebsiteRepository

class SearchForm(forms.Form):
   websiterepository = WebsiteRepository


   env_indicators =  websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
   indicator = forms.ChoiceField(choices=env_indicators,label = 'Indicator'      )


  OPTIONS = (('2000','2000'),('2001','2001'),('2002','2002'), ('2003','2003'),('0000','0000'),)
   year = forms.ChoiceField(choices=OPTIONS)





class SelectTypeForm(forms.Form): 

      OPTIONS = (('1', 'Envirnmental Indicators'),('2','Economic Indicators'),('3','Social Indicators'),)
      types = forms.ChoiceField(choices=OPTIONS)

标签: django

解决方案


您的代码在很多方面都是错误的。

首先要做的事情:对于搜索,您需要 GET 请求,而不是 POST(POST 用于更新服务器的状态 - 主要是添加或更新数据库)。这是语义正确的方法(因为您想获取数据),它将允许用户为 url 添加书签。

第二点:您不想将搜索表单提交给索引视图,而是提交给搜索视图。不需要重定向等,只需使用{% url %}模板标签来填写action表单的属性(您当然需要在 urls.py 中有一个“搜索”网址):

<form method="get" action="{% url 'Search' %}">
   {% csrf_token %}
   {{form.as_p}}
   <button type = 'submit'>submit</button>
  </form>

如果您想在多个页面上使用此表单(搜索表单通常是这种情况),请使用包含标记,它将负责创建未绑定的 SearchForm 并呈现模板片段。

然后在你的搜索视图中,你只想要 GET 请求,并且不要使用两个不同的模板,这只会导致无用的重复。

def Search(request):
    form = SearchForm(request.GET)
    # use the form's data - if any - to get search results 
    # and put those results (even if empty) in you context 
    return render(request, 'reply.html', {'env_dict':env_dict})

最后,您的搜索表单完全损坏:

class SearchForm(forms.Form):
   # this is totally useless
   websiterepository = WebsiteRepository

   # this will only be evaluated once at process startup, so you will
   # get stale data in production - and probably different data
   # per process, in a totally unpredictable way.
   # You need to either put this in the form's __init__ or wrap it
   # in a callable and pass this callable

   env_indicators =  websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')
   indicator = forms.ChoiceField(choices=env_indicators,label = 'Indicator'      )



  # are you going to manually add a new year choice every year ???
  OPTIONS = (('2000','2000'),('2001','2001'),('2002','2002'), ('2003','2003'),('0000','0000'),)
   year = forms.ChoiceField(choices=OPTIONS)

对于“指标”ChoiceField,您需要以下内容:

def get_indicators_choices():
    return Websiterepository.objects.filter (key_aspect='Environmental').values_list('repo_id','indicator')

class SearchForm(forms.Form):
   # IMPORTANT  : we are NOT calling the function here, just
   # passing it (python functions are objects) to the field, which
   # will call it everytime the form is instanciated, so you don't
   # have stale data
   indicator = forms.ChoiceField(
        choices=get_indicator_choices, 
        label='Indicator')

最后一点:与您的命名保持一致(即,为什么将一个视图全部命名为较低的 ( index) 而另一个大写 ( Search) ?无论您选择哪种约定(我强烈建议在此处尊重 pep8),至少在整个项目中坚持它.


推荐阅读