我正在使用 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)
您的代码在很多方面都是错误的。
首先:对于搜索,您需要 GET 请求,而不是 POST(POST 用于更新服务器的状态 - 主要是添加或更新您的数据库)。这是语义上正确的方法(因为您想要 GET 数据),它将允许用户为 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),至少在整个项目中坚持它.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句