如何在 Django 的一个 url 地址中调用多个视图?
How can I call multiple views in one url address in Django?
我试图在 index.html 上显示由 new_measurement 定义的表单,但我只设法让 IndexView()
工作。我尝试了 IndexView()
和 new_measurement()
之间的各种组合,但根本没有用。我知道 IndexView()
不会传递与 new_measurement()
相关的任何内容,并且不会调用 new_measurement()
,这是我问题的核心。如果对 Django 有更多经验的人能告诉我我能做什么或应该做什么,我将不胜感激。谢谢。
这是我的 views.py:
from django.shortcuts import render
from django.utils import timezone
from .models import Measurement
from .forms import MeasurementForm
from django.views import generic
class IndexView(generic.ListView):
model = Measurement
context_object_name = 'measurement_list'
template_name = 'index.html'
queryset = Measurement.objects.all()
def new_measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST)
if form.is_valid():
measurement = form.save(commit=False)
measurement.measurement_date = timezone.now()
measurement.save()
else:
form = MeasurementForm()
return render(request, 'index.html', {'form': form})
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
forms.py:
class MeasurementForm(forms.ModelForm):
class Meta:
model = Measurement
fields = ('measurement_value', 'measurement_unit')
index.html:
{% extends "base.html" %}
{% block content %}
<h1>Climate Measurement Tool</h1>
<h2>Add a new measurement</h2>
<form method="POST" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save">Add</button>
</form>
<h2>Measurements</h2>
{% if measurement_list %}
<ul>
{% for measurement in measurement_list %}
<li>
<p>{{ measurement }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>No measurements yet</p>
{% endif %}
{% endblock %}
你不能为一个 url 调用 2 个视图。基本上每个 url 都必须链接到一个视图,这是你无法真正改变的。
但是如果你想让你的代码更简洁,有多个功能,你可以在你的视图中调用它们,基本上你可以做一个视图并在 url 甚至更多时调用它超过一个 url 已被使用,在该视图中决定使用哪个函数
示例:
def god_view(request):
if request.method == "POST"
return post_func(request)
return get_func(request)
这是一个非常简单的示例,但您可以做很多其他事情。
您不能在一个视图中映射多个视图 url 但您可以在一个视图中执行多项工作。
更新您的 views.py,因为您可以看到我在该视图中发送(查询列表和表单)
views.py
def new_measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST)
if form.is_valid():
measurement = form.save(commit=False)
measurement.measurement_date = timezone.now()
measurement.save()
else:
form = MeasurementForm()
qs = Measurement.objects.all()
context = {'form': form, 'measurement_list': qs}
return render(request, 'index.html', context)
更新urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.new_measurement, name='index'),
]
不可能在一个中有更多的视图url,但是你可以模拟它。我这样做就像一个视图,在这个视图的模板中是 javascript,它用 AJAX
的响应加载第二个视图,并用第二个视图的内容填充所属元素。第二个视图不是整个模板,但它以一些 div
标签开始,这些标签被放置在第一个模板中。我会试着给你举个例子
观看次数
def first_view(request):
return render(
request,
'first_template.html',
{
'first_content': 'Some heavy content'
})
def second_view(request):
return render(
request,
'second_template.html',
{
'second_content': 'Some heavier content!'
})
first_template.html
...
<body>
<div id="1">
{{ first_content }}
</div>
<div>
... loading ...
</div>
<script>
window.onload = function() {
$.ajax({
url: {% url 'to_second_view' %},
method: 'GET',
success: function(response) {
$('#2').html(response);
}
})
}
</script>
</body>
...
second_template.html
<div>
{{ second_content }}
</div>
如果您正在使用 cbv,您可以为继承 TemplateResponseMixin
和 return 的任何视图重写 get_template_names
方法,按顺序搜索字符串列表,直到匹配或ImporperlyConfigured
提出。例如:
class SomeView(TemplateResponseMixin):
...
def get_template_names(self):
if self.request.method == "POST":
return ['post_template.html']
else:
return ['template.html']
我试图在 index.html 上显示由 new_measurement 定义的表单,但我只设法让 IndexView()
工作。我尝试了 IndexView()
和 new_measurement()
之间的各种组合,但根本没有用。我知道 IndexView()
不会传递与 new_measurement()
相关的任何内容,并且不会调用 new_measurement()
,这是我问题的核心。如果对 Django 有更多经验的人能告诉我我能做什么或应该做什么,我将不胜感激。谢谢。
这是我的 views.py:
from django.shortcuts import render
from django.utils import timezone
from .models import Measurement
from .forms import MeasurementForm
from django.views import generic
class IndexView(generic.ListView):
model = Measurement
context_object_name = 'measurement_list'
template_name = 'index.html'
queryset = Measurement.objects.all()
def new_measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST)
if form.is_valid():
measurement = form.save(commit=False)
measurement.measurement_date = timezone.now()
measurement.save()
else:
form = MeasurementForm()
return render(request, 'index.html', {'form': form})
urls.py:
from django.urls import path
from . import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
]
forms.py:
class MeasurementForm(forms.ModelForm):
class Meta:
model = Measurement
fields = ('measurement_value', 'measurement_unit')
index.html:
{% extends "base.html" %}
{% block content %}
<h1>Climate Measurement Tool</h1>
<h2>Add a new measurement</h2>
<form method="POST" class="post-form">
{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save">Add</button>
</form>
<h2>Measurements</h2>
{% if measurement_list %}
<ul>
{% for measurement in measurement_list %}
<li>
<p>{{ measurement }}</p>
</li>
{% endfor %}
</ul>
{% else %}
<p>No measurements yet</p>
{% endif %}
{% endblock %}
你不能为一个 url 调用 2 个视图。基本上每个 url 都必须链接到一个视图,这是你无法真正改变的。
但是如果你想让你的代码更简洁,有多个功能,你可以在你的视图中调用它们,基本上你可以做一个视图并在 url 甚至更多时调用它超过一个 url 已被使用,在该视图中决定使用哪个函数
示例:
def god_view(request):
if request.method == "POST"
return post_func(request)
return get_func(request)
这是一个非常简单的示例,但您可以做很多其他事情。
您不能在一个视图中映射多个视图 url 但您可以在一个视图中执行多项工作。 更新您的 views.py,因为您可以看到我在该视图中发送(查询列表和表单)
views.py
def new_measurement(request):
if request.method == "POST":
form = MeasurementForm(request.POST)
if form.is_valid():
measurement = form.save(commit=False)
measurement.measurement_date = timezone.now()
measurement.save()
else:
form = MeasurementForm()
qs = Measurement.objects.all()
context = {'form': form, 'measurement_list': qs}
return render(request, 'index.html', context)
更新urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.new_measurement, name='index'),
]
不可能在一个中有更多的视图url,但是你可以模拟它。我这样做就像一个视图,在这个视图的模板中是 javascript,它用 AJAX
的响应加载第二个视图,并用第二个视图的内容填充所属元素。第二个视图不是整个模板,但它以一些 div
标签开始,这些标签被放置在第一个模板中。我会试着给你举个例子
观看次数
def first_view(request):
return render(
request,
'first_template.html',
{
'first_content': 'Some heavy content'
})
def second_view(request):
return render(
request,
'second_template.html',
{
'second_content': 'Some heavier content!'
})
first_template.html
...
<body>
<div id="1">
{{ first_content }}
</div>
<div>
... loading ...
</div>
<script>
window.onload = function() {
$.ajax({
url: {% url 'to_second_view' %},
method: 'GET',
success: function(response) {
$('#2').html(response);
}
})
}
</script>
</body>
...
second_template.html
<div>
{{ second_content }}
</div>
如果您正在使用 cbv,您可以为继承 TemplateResponseMixin
和 return 的任何视图重写 get_template_names
方法,按顺序搜索字符串列表,直到匹配或ImporperlyConfigured
提出。例如:
class SomeView(TemplateResponseMixin):
...
def get_template_names(self):
if self.request.method == "POST":
return ['post_template.html']
else:
return ['template.html']