你将创建一些表单,让用户能够添加主题和条目,以及编辑既有的条目。你还将学习Django如何防范对基于表单的网页发起的常见攻击,这让你无需花太多时间考虑确保应用程序安全的问题。

然后,我们将实现一个用户身份验证系统。你将创建一个注册页面,供用户创建账户,并让有些页面只能供已登录的用户访问。接下来,我们将修改一些视图函数, 使得用户只能看到自己的数据。你将学习如何确保用户数据的安全。

1、让用户能够输入数据

建立用于创建用户账户的身份验证系统之前,我们先来添加几个页面,让用户能够输入数据。我们将让用户能够添加新主题、添加新条目以及编辑既有条目。
当前,只有超级用户能够通过管理网站输入数据。我们不想让用户与管理网站交互,因此我们将使用Django的表单创建工具来创建让用户能够输入数据的页面。

1.1 添加新主题

创建基于表单的页面的方法几乎与前面创建网页一样:定义一个URL,编写一个视图函数并编写一个模板。一个主要差别是,需要导入包含表单的模块forms.py。

(1)创建表单

让用户输入并提交信息的页面都是表单,哪怕它看起来不像表单。用户输入信息时,我们需要进行验证,确认提供的信息是正确的数据类型,且不是恶意的信息,如中断服务器的代码。然后,我们再对这些有效信息进行处理,并将其保存到数据库的合适地方。这些工作很多都是由Django自动完成的。 在Django中,创建表单的最简单方式是使用ModelForm,它根据我们在python-Django实践的模型中的信息自动创建表单。创建一个名为forms.py的文件,将其存储到models.py所在的目录
中,并在其中编写你的第一个表单:

from django import forms

from .models import Topic

class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''}

我们首先导入了模块forms 以及要使用的模型Topic 。我们定义了一个名为TopicForm 的类,它继承了forms.ModelForm 。最简单的ModelForm 版本只包含一个内嵌的Meta 类,它告诉Django根据哪个模型创建表单,以及在表单中包含哪些字段。我们根据模型Topic 创建一个表单,该表单只包含字段text (的代码让Django不要为字段text 生成标签。

(2)URL模式new_topic

这个新网页的URL应简短而具有描述性,因此当用户要添加新主题时,我们将切换到http://localhost:8000/new_topic/。下面是网页new_topic 的URL模式,我们将其添加到 learning_logs/urls.py中:

"""定义learning_logs的URL模式"""

from django.conf.urls import url

from . import views
app_name='learning_logs' urlpatterns = [
# 主页
url(r'^$', views.index, name='index'), # 显示所有的主题
url(r'^topics/$', views.topics, name='topics'), # 制定主题的详细页面
url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'), # 用于添加新主题的网页
url(r'^new_topic/$', views.new_topic, name='new_topic'),
]

(3)视图函数new_topic()

修改views.py,函数new_topic() 需要处理两种情形:刚进入new_topic 网页(在这种情况下,它应显示一个空表单);对提交的表单数据进行处理,并将用户重定向到网页topics :

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse from .models import Topic
from .forms import TopicForm def index(request):
"""学习笔记的主页"""
return render(request, 'learning_logs/index.html') def topics(request):
"""显示所有的主题"""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context) def topic(request, topic_id):
"""显示特定主题的详细页面"""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context) def new_topic(request):
"""添加新主题"""
if request.method != 'POST':
# 未提交数据:创建一个新表单
form = TopicForm()
else:
# POST提交的数据,对数据进行处理
form = TopicForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context)

我们导入了HttpResponseRedirect 类,用户提交主题后我们将使用这个类将用户重定向到网页topics 。函数reverse() 根据指定的URL模型确定URL,这意味着Django 将在页面被请求时生成URL。我们还导入了刚才创建的表单TopicForm 。

(4)GET请求和POST请求

创建Web应用程序时,将用到的两种主要请求类型是GET请求和POST请求。对于只是从服务器读取数据的页面,使用GET请求;在用户需要通过表单提交信息时,通常使用POST请求。

处理所有表单时,我们都将指定使用POST方法。还有一些其他类型的请求,但这个项目没有使用。
函数new_topic() 将请求对象作为参数。用户初次请求该网页时,其浏览器将发送GET请求;

用户填写并提交表单时,其浏览器将发送POST请求。

根据请求的类型,我们可以确定用户请求的是空表单(GET请求)还是要求对填写好的表单进行处理(POST请求)。

❶处的测试确定请求方法是GET还是POST。如果请求方法不是POST,请求就可能是GET,因此我们需要返回一个空表单(即便请求是其他类型的,返回一个空表单也不会有任何 问题)。我们创建一个TopicForm 实例(见❷),将其存储在变量form 中,再通过上下文字典将这个表单发送给模板context(见❼)。由于实例化TopicForm 时我们没有指定任何 实参,Django将创建一个可供用户填写的空表单。
如果请求方法为POST,将执行else 代码块,对提交的表单数据进行处理。我们使用用户输入的数据(它们存储在request.POST 中)创建一个TopicForm 实例(见❸), 这样对象form 将包含用户提交的信息。
要将提交的信息保存到数据库,必须先通过检查确定它们是有效的(见❹)。函数is_valid() 核实用户填写了所有必不可少的字段(表单字段默认都是必不可少的),且输入 的数据与要求的字段类型一致(例如,字段text 少于200个字符,这是我们在第18章中的models.py中指定的)。这种自动验证避免了我们去做大量的工作。如果所有字段都有 效,我们就可调用save() (见❺),将表单中的数据写入数据库。保存数据后,就可离开这个页面了。我们使用reverse() 获取页面topics 的URL,并将其传递 给HttpResponseRedirect() (见❻),后者将用户的浏览器重定向到页面topics 。在页面topics 中,用户将在主题列表中看到他刚输入的主题。

5. 模板new_topic

下面来创建新模板new_topic.html,用于显示我们刚创建的表单:

{% extends "learning_logs/base.html" %}

{% block content %}
<p>Add a new topic:</p> <form action="{% url 'learning_logs:new_topic' %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">add topic</button>
</form> {% endblock content %}

这个模板继承了base.html,因此其基本结构与项目“学习笔记”的其他页面相同。

  • 实参action 告诉服务器将提交的表单数据发送到哪里,这 里我们将它发回给视图函数new_topic() 。实参method 让浏览器以POST请求的方式提交数据。
  • Django使用模板标签{% csrf_token %} 来防止攻击者利用表单来获得对服务器未经授权的访问(这种攻击被称为跨站请求伪造 )
  • 我们只需包含模板变量{{ form.as_p }},就可让Django自动创建显示表单所需的全部字段。修饰符as_p让Django以段落格式渲 染所有表单元素,这是一种整洁地显示表单的简单方式。
  • Django不会为表单创建提交按钮,因此定义了一个这样的按钮。

6、链接到页面new_topic

接下来,我们在页面topics.html 中添加一个到页面new_topic 的链:

{% extends "learning_logs/base.html" %}

{% block content %}

<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
<a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
<a href="{% url 'learning_logs:new_topic' %}">Add a new topic:</a> {% endblock content %}

这个链接放在了既有主题列表的后面。下图显示了生成的表单。请使用这个表单来添加几个新主题。

1.2 添加新条目

现在用户可以添加新主题了,但他们还想添加新条目。我们将再次定义URL,编写视图函数和模板,并链接到添加新条目的网页。但在此之前,我们需要在forms.py中再添加一个 类。

(1)用于添加新条目的表单

我们需要在forms.py创建一个与模型Entry 相关联的表单,但这个表单的定制程度比TopicForm 要高些:

from django import forms

from .models import Topic, Entry

class TopicForm(forms.ModelForm):
class Meta:
model = Topic
fields = ['text']
labels = {'text': ''} class EntryForm(forms.ModelForm):
class Meta:
model = Entry
fields = ['text']
labels = {'text': ''}
widgets = {'text': forms.Textarea(attrs={'cols': 80})}
  • 我们首先修改了import 语句,使其除导入Topic 外,还导入Entry 。新类EntryForm 继承了forms.ModelForm ,它包含的Meta 类指出了表单基于的模型以及要在表单 中包含哪些字段。这里也给字段'text' 指定了一个空标签。
  • 我们定义了属性widgets 。小部件 (widget)是一个HTML表单元素,如单行文本框、多行文本区域或下拉列表。通过设置属性widgets ,可覆盖Django选择的默认小 部件。通过让Django使用forms.Textarea ,我们定制了字段'text' 的输入小部件,将文本区域的宽度设置为80列,而不是默认的40列。这给用户提供了足够的空间,可以 编写有意义的条目。

(2) URL模式new_entry

在用于添加新条目的页面的URL模式中,需要包含实参topic_id ,因为条目必须与特定的主题相关联。该URL模式如下,我们将它添加到了learning_logs/urls.py中:

"""定义learning_logs的URL模式"""

from django.conf.urls import url

from . import views
app_name='learning_logs' urlpatterns = [
# 主页
url(r'^$', views.index, name='index'), # 显示所有的主题
url(r'^topics/$', views.topics, name='topics'), # 制定主题的详细页面
url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'), # 用于添加新主题的网页
url(r'^new_topic/$', views.new_topic, name='new_topic'), # 用于添加新条目的页面
url(r'^new_entry/(?P<topic_id>\d+)/$', views.new_entry, name='new_entry'),
]

这个URL模式与形式为http://localhost:8000/new_entry/id / 的URL匹配,其中 id 是一个与主题ID匹配的数字。代码(?P<topic_id>\d+) 捕获一个数字值,并 将其存储在变量topic_id 中。请求的URL与这个模式匹配时,Django将请求和主题ID发送给函数new_entry() 。
(3)视图函数new_entry()

视图函数new_entry() 与函数new_topic() 很像,在views.py中添加:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse from .models import Topic
from .forms import TopicForm,EntryForm def index(request):
"""学习笔记的主页"""
return render(request, 'learning_logs/index.html') def topics(request):
"""显示所有的主题"""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context) def topic(request, topic_id):
"""显示特定主题的详细页面"""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context) def new_topic(request):
"""添加新主题"""
if request.method != 'POST':
# 未提交数据:创建一个新表单
form = TopicForm()
else:
# POST提交的数据,对数据进行处理
form = TopicForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context) def new_entry(request, topic_id):
"""在特定的主题中添加新条目"""
topic = Topic.objects.get(id=topic_id) if request.method != 'POST':
# 未提交数据,创建一个空表单
form = EntryForm()
else:
# POST提交的数据,对数据进行处理
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return HttpResponseRedirect(reverse('learning_logs:topic',
args=[topic_id]))
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context)
  • 我们修改了import 语句,在其中包含了刚创建的EntryForm 。new_entry() 的定义包含形参topic_id ,用于存储从URL中获得的值。渲染页面以及处理表单数据时,都 需要知道针对的是哪个主题,因此我们使用topic_id 来获得正确的主题。
  • 我们检查请求方法是POST还是GET。如果是GET请求,将执行if 代码块:创建一个空的EntryForm 实例。如果请求方法为POST,我们就对数据进行处理: 创建一个EntryForm 实例,使用request 对象中的POST数据来填充它;再检查表单是否有效,如果有效,就设置条目对象的属性topic ,再将条目对象保存到数据 库。
  • 调用save() 时,我们传递了实参commit=False ,让Django创建一个新的条目对象,并将其存储到new_entry 中,但不将它保存到数据库中。我们将new_entry 的属性topic 设置为在这个函数开头从数据库中获取的主题,然后调用save() ,且不指定任何实参。这将把条目保存到数据库,并将其与正确的主题相关联。
  • 我们将用户重定向到显示相关主题的页面。调用reverse() 时,需要提供两个实参:要根据它来生成URL的URL模式的名称;列表args ,其中包含要包含在URL中的 所有实参。在这里,列表args 只有一个元素——topic_id 。接下来,调用HttpResponseRedirect() 将用户重定向到显示新增条目所属主题的页面,用户将在该页面的 条目列表中看到新添加的条目。

(4)模板new_entry

模板new_entry.html 类似于模板new_topic.html :

{% extends "learning_logs/base.html" %}

{% block content %}

  <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
<p>Add a new entry:</p> <form action="{% url 'learning_logs:new_entry' topic.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name='submit'>add entry</button>
</form>
{% endblock content %}

我们在页面顶端显示了主题,让用户知道他是在哪个主题中添加条目;该主题名也是一个链接,可用于返回到该主题的主页面。 表单的实参action 包含URL中的topic_id 值,让视图函数能够将新条目关联到正确的主题。除此之外,这个模板与模板new_topic.html完全相同。

(5)链接到页面new_entry

我们需要在topic.html显示特定主题的页面中添加到页面new_entry 的链接:

{% extends 'learning_logs/base.html' %}

{% block content %}

<p>Topic: {{ topic }}</p>
<p>Entries:</p>
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
</p>
<ul>
{% for entry in entries %}
<li>
<p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
</li>
{% empty %}
<li>
There are no entries for this topic yet.
</li>
{% endfor %}
</ul>
{% endblock content %}

我们在显示条目前添加链接,因为在这种页面中,执行的最常见的操作是添加新条目。下图显示了页面new_entry 。现在用户可以添加新主题,还可以在每个主题中添加任 意数量的条目。请在一些既有主题中添加一些新条目,尝试使用一下页面new_entry 。

1.3 编辑条目

下面来创建一个页面,让用户能够编辑既有的条目。

(1)URL模式edit_entry

这个页面的URL需要传递要编辑的条目的ID。修改后的learning_logs/urls.py如下:

"""定义learning_logs的URL模式"""

from django.conf.urls import url

from . import views
app_name='learning_logs' urlpatterns = [
# 主页
url(r'^$', views.index, name='index'), # 显示所有的主题
url(r'^topics/$', views.topics, name='topics'), # 制定主题的详细页面
url(r'^topics/(?P<topic_id>\d+)/$', views.topic, name='topic'), # 用于添加新主题的网页
url(r'^new_topic/$', views.new_topic, name='new_topic'), # 用于添加新条目的页面
url(r'^new_entry/(?P<topic_id>\d+)/$', views.new_entry, name='new_entry'), # 用户编辑条目的页面
url(r'^edit_entry/(?P<entry_id>\d+)/$', views.edit_entry, name='edit_entry'),
]

在URL(如http://localhost:8000/edit_entry/1/)中传递的ID存储在形参entry_id 中。这个URL模式将预期匹配的请求发送给视图函数edit_entry() 。

(2)视图函数edit_entry()
修改视图views.py,页面edit_entry 收到GET请求时,edit_entry() 将返回一个表单,让用户能够对条目进行编辑。该页面收到POST请求(条目文本经过修订)时,它将修改后的文本保存到数据库中:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse from .models import Topic, Entry
from .forms import TopicForm,EntryForm def index(request):
"""学习笔记的主页"""
return render(request, 'learning_logs/index.html') def topics(request):
"""显示所有的主题"""
topics = Topic.objects.order_by('date_added')
context = {'topics': topics}
return render(request, 'learning_logs/topics.html', context) def topic(request, topic_id):
"""显示特定主题的详细页面"""
topic = Topic.objects.get(id=topic_id)
entries = topic.entry_set.order_by('-date_added')
context = {'topic': topic, 'entries': entries}
return render(request, 'learning_logs/topic.html', context) def new_topic(request):
"""添加新主题"""
if request.method != 'POST':
# 未提交数据:创建一个新表单
form = TopicForm()
else:
# POST提交的数据,对数据进行处理
form = TopicForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topics'))
context = {'form': form}
return render(request, 'learning_logs/new_topic.html', context) def new_entry(request, topic_id):
"""在特定的主题中添加新条目"""
topic = Topic.objects.get(id=topic_id) if request.method != 'POST':
# 未提交数据,创建一个空表单
form = EntryForm()
else:
# POST提交的数据,对数据进行处理
form = EntryForm(data=request.POST)
if form.is_valid():
new_entry = form.save(commit=False)
new_entry.topic = topic
new_entry.save()
return HttpResponseRedirect(reverse('learning_logs:topic',
args=[topic_id]))
context = {'topic': topic, 'form': form}
return render(request, 'learning_logs/new_entry.html', context) def edit_entry(request, entry_id):
"""编辑既有条目"""
entry = Entry.objects.get(id=entry_id)
topic = entry.topic if request.method != 'POST':
# 初次请求,使用当前条目填充表单
form = EntryForm(instance=entry)
else:
# POST提交的数据,对数据进行处理
form = EntryForm(instance=entry, data=request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('learning_logs:topic',
args=[topic.id]))
context = {'entry': entry, 'topic': topic, 'form': form}
return render(request, 'learning_logs/edit_entry.html', context)

我们首先需要导入模型Entry 。我们获取用户要修改的条目对象,以及与该条目相关联的主题。在请求方法为GET时将执行的if 代码块中,我们使用实 参instance=entry 创建一个EntryForm 实例。这个实参让Django创建一个表单,并使用既有条目对象中的信息填充它。用户将看到既有的数据,并能够编辑它们。

处理POST请求时,我们传递实参instance=entry 和data=request.POST ,让Django根据既有条目对象创建一个表单实例,并根据request.POST 中的相关数 据对其进行修改。然后,我们检查表单是否有效,如果有效,就调用save() ,且不指定任何实参。接下来,我们重定向到显示条目所属主题的页面,用户将 在其中看到其编辑的条目的新版本。

(3)模板edit_entry

下面是模板edit_entry.html,它与模板new_entry.html类似:

{% extends "learning_logs/base.html" %}

{% block content %}

  <p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a></p>
<p>Edit entry:</p> <form action="{% url 'learning_logs:edit_entry' entry.id %}" method='post'>
{% csrf_token %}
{{ form.as_p }}
<button name="submit">save changes</button>
</form>
{% endblock content %}

实参action将表单发回给函数edit_entry()进行处理。在标签{% url %}中,我们将条目ID作为一个实参,让视图对象能够修改正确的条目对象。我们将提交按 钮命名为save changes,以提醒用户:单击该按钮将保存所做的编辑,而不是创建一个新条目。

(4) 链接到页面edit_entry

在显示特定主题的页面中,需要给每个条目添加到页面edit_entry 的链接,修改topic.html:

{% extends 'learning_logs/base.html' %}

{% block content %}

<p>Topic: {{ topic }}</p>
<p>Entries:</p>
<p>
<a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
</p>
<ul>
{% for entry in entries %}
<li>
<p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
<p>{{ entry.text|linebreaks }}</p>
<p>
<a href="{% url 'learning_logs:edit_entry' entry.id %}">edit entry</a>
</p>
</li>
{% empty %}
<li>
There are no entries for this topic yet.
</li>
{% endfor %}
</ul>
{% endblock content %}

我们将编辑链接放在每个条目的日期和文本后面。在循环中,我们使用模板标签{% url %}根据URL模式edit_entry和当前条目的ID属性(entry.id)来确定URL。链接 文本为"edit entry",它出现在页面中每个条目的后面。下图显示了包含这些链接时,显示特定主题的页面是什么样的。

参考:

1、python编程,从入门到实践

Django web编程2 -- 编辑页面内容的更多相关文章

  1. Django web编程1 -- 创建项目和应用

    python:3.7.2 Django:2.1.7 1.创建虚拟环境 虚拟环境是系统的一个位置,可以在其中安装包,并将其与其他python包隔离. 创建目录,命名为learning_log,并切换到这 ...

  2. Django web编程3 -- 创建用户账户

    我们将建立一个用户注册和身份验证系统,让用户能够注册账户,进而登录和注销.我们将创建一个新的应用程序,其中包含与处理用户账户相关的所有功能.我们还将对模型Topic 稍做修改,让每个主题都归属于特定用 ...

  3. PHP求职宝典系列——PHP Web 编程篇

    PHP Web 编程篇 form表单 1.简述 POST 和 GET 传输的最大容量分别是多少? GET 方法提交的表单数据被附加到 URL 上,并作为URL 的一部分发送到服务器端. URL 的长度 ...

  4. Web编程基础--HTML、CSS、JavaScript 学习之课程作业“仿360极速浏览器新标签页”

    Web编程基础--HTML.CSS.JavaScript 学习之课程作业"仿360极速浏览器新标签页" 背景: 作为一个中专网站建设出身,之前总是做静态的HTML+CSS+DIV没 ...

  5. 物联网网络编程、Web编程综述

    本文是基于嵌入式物联网研发工程师的视觉对网络编程和web编程进行阐述.对于专注J2EE后端服务开发的童鞋们来说,这篇文章可能稍显简单.但是网络编程和web编程对于绝大部分嵌入式物联网工程师来说是一块真 ...

  6. 《Web编程入门经典》

    在我还不知道网页的基础结构的时候,我找过很多本介绍Web基础的书籍,其中这本<Web编程入门经典>,我认为是最好的. 这本书内容很全面.逻辑很严谨.结构很清晰.语言文字浅显易懂. 看这本书 ...

  7. MVC 5 Web编程2 -- URL映射

    ASP.NET MVC 5 Web编程2 -- URL映射(路由原理) 2015-02-12 08:50 by hangwei, 704 阅读, 5 评论, 收藏, 编辑 本章将讲述ASP.NET M ...

  8. 教程:Visual Studio 中的 Django Web 框架入门

    教程:Visual Studio 中的 Django Web 框架入门 Django 是高级 Python 框架,用于快速.安全及可扩展的 Web 开发. 本教程将在 Visual Studio 提供 ...

  9. Django Web开发学习笔记(1)

    一.Python的标准类型 (1)bool型 >>> bool("") False >>> bool(None) False >>& ...

随机推荐

  1. Github 快速建库上传本地代码

    1 github.com网页端先建好一个空库 2 本地对这个库进行 git clone 3 向本地库中添加已完成文件 4 运行如下命令 git add . (注:别忘记后面的.,此操作是把Test文件 ...

  2. Windows下创建ArcGIS Server站点

    原创文章,转载须标明出处自: https://www.cnblogs.com/gisspace/p/8126261.html ------------------------------------- ...

  3. arcgis api 3.x for js 实现克里金插值渲染图不依赖 GP 服务(附源码下载)

    前言 关于本篇功能实现用到的 api 涉及类看不懂的,请参照 esri 官网的 arcgis api 3.x for js:esri 官网 api,里面详细的介绍 arcgis api 3.x 各个类 ...

  4. (办公)mybatis工作中常见的问题(不定时更新)

    1.mybatis的like查询的方式. <if test="shopName != null and shopName != ''"> <bind name=& ...

  5. JMeter写入文件

    之前我们推文讨论过如何使用jmeter读取文件, 比如csv, txt文件读取, 只要配置csv数据文件, 即可非常容易的从文件中读取想要的数据,  但是如果数据已经从API或者DB中获取, 想存放到 ...

  6. ORA-12520 TroubleShooting

      同事反馈他连接一个新搭建的测试数据库时,报"ORA-12520: TNS: 监听程序无法为请求的服务器类型找到可用的处理程序"错误,在解决他这个问题时,顺便分析.总结一下ORA ...

  7. nginx预防常见攻击

    目录 nginx防止DDOS攻击 概述 攻击手段 配置 限制请求率 限制连接的数量 关闭慢连接 设置 IP 黑名单 设置IP白名单 小站点解决方案 nginx防止CC攻击 概述 主动抑制方法 应用举例 ...

  8. 关于Java 中跳出多重循环

    前言 环境:window10 JDK 1.8 应用场景:在多个for循环或while循环中,直接跳到最外层的循环外面,而不是需要层层退出来. 使用: 使用一个标签label(也可以是其他单词,不能是关 ...

  9. Java 控制结构与方法

    控制结构: 控制结构是对我们程序执行顺序的一种控制,它规定了我们语句块的执行顺序和流程. 分支结构: 关系运算符和逻辑运算符: 关系运算符:== != > >= < <=逻辑运 ...

  10. lua os.date函数定义和示例

    os.date函数定义 原型:os.date ([format [, time]]) 解释:返回一个按format格式化日期.时间的字串或表. lua源码中os.date的注释如下: --- --- ...