Django框架11 /form组件、modelForm组件
Django框架11 /form组件、modelForm组件
1. form组件介绍
form组件的主要功能如下:
- 生成页面可用的HTML标签
- 对用户提交的数据进行校验
- 保留上次输入内容
简单代码示例:
view.py
from django.shortcuts import render,HttpResponse,redirect
from django import forms class Auth(forms.Form):
username = forms.CharField(
label='用户名',
)
password = forms.CharField(
label='密 码',
# 控制前端显示样式
widget=forms.widgets.PasswordInput.attrs.update({'class':'c1'})
) def index(request):
u_obj = Auth()
return render(request,'index.html',{'u_obj':u_obj})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.c1{
background-color:darkgrey;
}
</style>
</head> <body>
<h1>测试页面</h1>
<div>
{{ u_obj.username.label }} {{ u_obj.username }}
</div>
<div>
{{ u_obj.password.label }} {{ u_obj.password }}
</div>
</body> <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.js"></script>
<script></script>
</html>
2. form常用字段与插件
创建Form类时,主要涉及到 【字段】 和 【插件】,字段用于对用户请求数据的验证,插件用于自动生成HTML;
initial --- 初始值/input框里面的初始值
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名", # 备注,在生成前端页面时使用
initial="张三", # 设置默认值
)
pwd = forms.CharField(min_length=6, label="密码")
error_messages --- 重写错误信息
class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
}
)
pwd = forms.CharField(min_length=6, label="密码")
password
class LoginForm(forms.Form):
...
pwd = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
) # 这个密码字段和其他字段不一样,默认在前端输入数据错误的时候,点击提交之后,默认是不保存的原来数据的,但是可以通过这个render_value=True让这个字段在前端保留用户输入的数据
RadioSelect --- 单radio值为字符串
class LoginForm(forms.Form):
gender = forms.fields.ChoiceField(
choices=((1, "男"), (2, "女"), (3, "保密")),
label="性别",
initial=3,
widget=forms.widgets.RadioSelect()
) # 样式是小圆圈单选
Select --- 单选
class LoginForm(forms.Form):
...
hobby = forms.fields.ChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=3,
widget=forms.widgets.Select()
) # 注意,单选框下拉框用的是ChoiceField,并且里面的插件是Select,不然验证的时候会报错, Select a valid choice的错误。
# 样式是单选下拉框
Select --- 多选
class LoginForm(forms.Form):
...
hobby = forms.fields.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
label="爱好",
initial=[1, 3],
widget=forms.widgets.SelectMultiple()
) # 多选框的时候用MultipleChoiceField,并且里面的插件用的是SelectMultiple,不然验证的时候会报错。
# 样式是多选下拉框
checkbox --- 单选
class LoginForm(forms.Form):
...
keep = forms.fields.ChoiceField(
label="是否记住密码",
initial="checked",
widget=forms.widgets.CheckboxInput()
) # 样式是单选小方块
checkbox --- 多选
class LoginForm(forms.Form):
...
hobby = forms.fields.MultipleChoiceField(
choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
label="爱好",
initial=[1, 3],
widget=forms.widgets.CheckboxSelectMultiple()
) # 样式是多选小方块
date类型
from django import forms
from django.forms import widgets
class BookForm(forms.Form):
date = forms.DateField(widget=widgets.TextInput(attrs={'type':'date'})) # 必须指定type,不然不能渲染成选择时间的input框
choice字段注意事项
在使用选择标签时,需要注意choices的选项可以配置从数据库中获取,但是由于是静态字段 获取的值无法实时更新,需要重写构造方法从而实现choice实时更新。
方式一:
from django.forms import Form
from django.forms import widgets
from django.forms import fields class MyForm(Form): user = fields.ChoiceField(
# choices=((1, '上海'), (2, '北京'),),
initial=2,
widget=widgets.Select
) def __init__(self, *args, **kwargs):
super(MyForm,self).__init__(*args, **kwargs)
self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption') # 注意:重写init方法的时候,*args和**kwargs一定要给人家写上,不然会出问题,并且验证总是不能通过,还不显示报错信息
方式二:
from django import forms
from django.forms import fields
from django.forms import models as form_model class FInfo(forms.Form):
# 多选
authors = forms.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())
# 多选 -- 或者下面这种方式,通过forms里面的models中提供的方法也是一样的。
authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())
# 单选
authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())
# 单选
authors = forms.ModelChoiceField(queryset=models.Publisth.objects.all(),
widget=forms.widgets.Select()) authors = forms.ModelMultipleChoiceField(queryset=models.Author.objects.all(),
widget = forms.widgets.Select(attrs={'class': 'form-control'})) # 如果用这种方式,别忘了model表中的__str__方法要写上,不然选择框里面会是一个个的object对象
3. form所有内置字段
代码示例:
Field
required=True, # 是否允许为空
widget=None, # HTML插件
label=None, # 用于生成Label标签或显示内容
initial=None, # 初始值
help_text='', # 帮助信息(在标签旁边显示)
error_messages=None, # 错误信息 {'required': '不能为空', 'invalid': '格式错误'}
validators=[], # 自定义验证规则
localize=False, # 是否支持本地化
disabled=False, # 是否可以编辑
label_suffix=None # Label内容后缀 CharField(Field)
max_length=None, # 最大长度
min_length=None, # 最小长度
strip=True # 是否移除用户输入空白 IntegerField(Field)
max_value=None, # 最大值
min_value=None, # 最小值 FloatField(IntegerField)
... DecimalField(IntegerField)
max_value=None, # 最大值
min_value=None, # 最小值
max_digits=None, # 总长度
decimal_places=None, # 小数位长度 DateField(BaseTemporalField) # 格式:2015-09-01 RegexField(CharField)
regex, # 自定制正则表达式
max_length=None, # 最大长度
min_length=None, # 最小长度
error_message=None, # 忽略,错误信息使用 error_messages={'invalid': '...'} EmailField(CharField)
... FileField(Field)
allow_empty_file=False # 是否允许空文件 ChoiceField(Field)
...
choices=(), # 选项,如:choices = ((0,'上海'),(1,'北京'),)
required=True, # 是否必填
widget=None, # 插件,默认select插件
label=None, # Label内容
initial=None, # 初始值
help_text='', # 帮助提示
4. form字段校验
RegexValidator验证器
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator class MyForm(Form):
user = fields.CharField(
validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
)
自定义验证函数
import re
from django.core.exceptions import ValidationError # 自定义验证规则
def mobile_validate(value):
mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
if not mobile_re.match(value):
raise ValidationError('手机号码格式错误')
# 自定义验证规则的时候,如果不符合你的规则,需要自己发起错误 class PublishForm(forms.Form):
# 使用自定义验证规则
phone = forms.CharField(validators=[mobile_validate, ],
error_messages={'required': '手机不能为空'},
widget=widgets.TextInput(attrs={'class': "form-control",
'placeholder': u'手机号码'}))
5. formHook钩子方法
局部钩子
# 我们在Fom类中定义 clean_字段名() 方法,就能够实现对特定字段进行校验。 class LoginForm(forms.Form):
username = forms.CharField(
min_length=8,
label="用户名",
initial="张三",
error_messages={
"required": "不能为空",
"invalid": "格式错误",
"min_length": "用户名最短8位"
},
widget=forms.widgets.TextInput(attrs={"class": "form-control"})
)
...
# 定义局部钩子,用来校验username字段,之前的校验规则还在,给你提供了一个添加一些校验功能的钩子
def clean_username(self):
value = self.cleaned_data.get("username")
if "666" in value:
raise ValidationError("光喊666是不行的")
else:
return value
全局钩子
# 在Fom类中定义 clean() 方法,就能够实现对字段进行全局校验,字段全部验证完,局部钩子也全部执行完之后,执行这个全局钩子校验 class LoginForm(forms.Form):
...
password = forms.CharField(
min_length=6,
label="密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}, render_value=True)
)
re_password = forms.CharField(
min_length=6,
label="确认密码",
widget=forms.widgets.PasswordInput(attrs={'class': 'form-control'}, render_value=True)
)
...
# 定义全局的钩子,用来校验密码和确认密码字段是否相同,执行全局钩子的时候,cleaned_data里面肯定是有了通过前面验证的所有数据
def clean(self):
password_value = self.cleaned_data.get('password')
re_password_value = self.cleaned_data.get('re_password')
if password_value == re_password_value:
return self.cleaned_data #全局钩子要返回所有的数据
else:
# 第一种方式:
self.add_error('re_password', '两次密码不一致') #在re_password这个字段的错误列表中加上一个错误
# 第二种方式:
raise ValidationError('两次密码不一致') #将错误添加到全局
6. form批量添加属性样式
代码示例:
# 批量添加属性样式
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
for field_name,field in self.fields.items(): #orderdict(('username',charfield对象))
field.widget.attrs.update({'class':'form-control'}
7. form代码示例
form字段/插件/钩子代码示例
from django.shortcuts import render,HttpResponse,redirect from django import forms from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError # 自定义验证规则
import re
def mobile_validate(value):
mobile_re = re.compile(r'^3')
if not mobile_re.match(value):
raise ValidationError('手机号格式错误') #自定义验证规则的时候,如果不符合你的规则,需要自己发起错误 class Auth(forms.Form):
username = forms.CharField(
# 前面信息
label='用户名',
# 默认值
initial='张三',
# 设置最小长度
min_length=6,
# 设置最大长度
max_length=8,
# #不允许为空,值为False就可以为空
required=True,
# 对错误信息重命名
error_messages={
'required':'不能为空',
'min_length':'最低6位',
}, # 直接写自定义规则验证
validators=[RegexValidator(r'^a','必须以a开头')] # 引用外部正则函数验证
validators=[mobile_validate] #[]中括号内写自定义的正则函数
widget=forms.TextInput(attrs={'class':'c2'})
) # 密码
password = forms.CharField(
label='密 码',
widget=forms.widgets.PasswordInput(attrs={'class':'c1'},render_value=True),
)
render_value=True # 将密码设置成再显示,密码一般输错不会再显示 # 确认密码
re_password = forms.CharField(
label='确认密码',
widget=forms.widgets.PasswordInput(attrs={'class':'c1'},render_value=True),
) # 性别--单选
sex = forms.ChoiceField(
choices=((1,'男'),(2,'女')),
# widget=forms.Select, #默认 单选下拉框
widget=forms.RadioSelect,
) # 爱好--多选
hobby = forms.MultipleChoiceField(
choices=((1, '抽烟'), (2, '喝酒'), (2, '烫头')),
# widget=forms.SelectMultiple, #默认 多选下拉框
widget=forms.CheckboxSelectMultiple,
) # 记住我--单选方块
remember_me = forms.ChoiceField(
label='记住我',
widget=forms.CheckboxInput
) # 日期格式 # 日期类型必须加上日期属性
bday = forms.DateField(
label='出生日期',
widget=forms.DateInput(attrs={'type':'date'})
) # 局部钩子
def clean_username(self):
value = self.cleaned_data.get('username')
if 'ergou' in value:
raise ValidationError('含有敏感词汇')
else:
return value # 全局钩子
def clean(self):
password = self.cleaned_data.get('password')
re_password = self.cleaned_data.get('re_password')
if password == re_password:
return self.cleaned_data
else:
self.add_error('re_password','两次密码不一致!!') def index(request):
if request.method == 'GET':
u_obj = Auth()
return render(request,'index.html',{'u_obj':u_obj})
else:
u_obj = Auth(request.POST)
print(u_obj.fields)
if u_obj.is_valid(): #校验用户提交的数据,全部校验成功返回True,任意一个失败都返回False
print('正确数据',u_obj.cleaned_data) #校验成功之后的数据cleaned_data
return HttpResponse('ok')
else:
print('错误信息',u_obj.errors)
return render(request,'index.html',{'u_obj':u_obj})
form组件应用代码示例:
view.py
from django import forms class AddBookForm(forms.Form):
title = forms.CharField(
label='书名',
)
price=forms.DecimalField(
label='价格',
max_digits=5,
decimal_places=2 , #999.99
)
publishDate=forms.CharField(
label='出版日期',
widget=forms.TextInput(attrs={'type':'date'}), )
# 单选方式一:
# publishs_id = forms.ChoiceField(
# choices=models.Publish.objects.all().values_list('id','name'), #[(),()]
# )
# 多选方式一:
# authors=forms.MultipleChoiceField(
# choices=models.Author.objects.all().values_list('id','name')
# ) # 单选方式二:
publishs = forms.ModelChoiceField(
queryset=models.Publish.objects.all(),
)
# 多选方式二:
authors = forms.ModelMultipleChoiceField(
queryset=models.Author.objects.all(),
) # csrfmiddlewaretoken = forms.ChoiceField
# 批量添加属性样式
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
for field_name,field in self.fields.items(): #orderdict(('username',charfield对象))
field.widget.attrs.update({'class':'form-control'}) def addbook(request):
if request.method == 'GET':
book_obj = AddBookForm()
return render(request,'addbook.html',{'book_obj':book_obj})
else:
book_obj = AddBookForm(request.POST)
print(request.POST)
if book_obj.is_valid():
print(book_obj.cleaned_data)
data = book_obj.cleaned_data
authors = data.pop('authors')
new_book = models.Book.objects.create(
**data
# publishs = 对象
)
new_book.authors.add(*authors) # return HttpResponse('ok')
return redirect('showbooks')
else:
return render(request,'addbook.html',{'book_obj':book_obj})addbook.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7-dist/css/bootstrap.min.css' %}">
</head>
<body>
<h1>添加书籍</h1>
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<form action="" method="post" novalidate>
{% csrf_token %}
{% for field in book_obj %}
<div class="form-group">
{{ field.label }}
{{ field }}
<span class="text-danger">{{ field.errors.0 }}</span>
</div>
{% endfor %}
<button type="submit" class="btn btn-success pull-right">提交</button>
</form>
</div>
</div>
</div>
</body>
</html>
7. modelForm
- 定义:form与model的终极结合,会根据model中的字段转换成对应的form字段,并且生成对应的标签等操作
8. modelform类的写法/class Meta下常用参数
modelform类的写法
class BookForm(forms.ModelForm): class Meta:
model = models.Book
fields = "__all__"
labels = {
"title": "书名",
"price": "价格"
}
widgets = {
"password": forms.widgets.PasswordInput(attrs={"class": "c1"}),
"publishDate": forms.widgets.DateInput(attrs={"type": "date"}),
}
class Meta下常用参数
model = models.Book # 对应的Model中的类
fields = "__all__" # 字段,如果是__all__,就是表示列出所有的字段
exclude = None # 排除的字段
labels = None # 提示信息
help_texts = None # 帮助提示信息
widgets = None # 自定义插件
error_messages = None # 自定义错误信息
error_messages = {
'title':{'required':'不能为空',...} # 每个字段的所有的错误都可以写,...是省略的意思
}
9. modelform钩子/批量添加
代码示例:
class BookForm(forms.ModelForm):
password = forms.CharField(min_length=10) # 优先级高
# 可以重写字段,会覆盖modelform中的这个字段,那么modelform下面关于这个字段的设置就会被覆盖,比如果设置插件啊,error_messages啊等等,
r_password = forms.CharField()
# 想多验证一些字段可以单独拿出来写,按照form的写法,写在Meta的上面或者下面都可以
class Meta:
model = models.Book
# fields = ['title','price'] # 指定字段生成form
fields = "__all__"
# exclude=['title',] #排除字段
labels = {
"title": "书名",
"price": "价格"
}
error_messages = {
'title':{'required':'不能为空',} # 每个字段的错误都可以写
}
# 如果models中的字段和咱们需要验证的字段对不齐时,比如注册时,咱们需要验证密码和确认密码两个字段数据,但是后端数据库就保存一个数据就行,那么验证是两个,数据保存是一个,就可以再接着写form字段
r_password = forms.CharField()
# 同样的,如果想做一些特殊的验证定制,那么和form一样,也是那两个钩子(全局和局部),写法也是form那个的写法,直接在咱们的类里面写: # 局部钩子:
def clean_title(self):
pass # 全局钩子
def clean(self):
pass # 批量操作
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs)
for field in self.fields:
# field.error_messages = {'required':'不能为空'}
# 批量添加错误信息,这是都一样的错误,不一样的还是要单独写。
self.fields[field].widget.attrs.update({'class':'form-control'})
10. modelForm验证/保存
modelForm验证
- 与普通的Form表单验证类型类似,ModelForm表单的验证在调用is_valid() 或访问errors 属性时隐式调用。
- 可以像使用Form类一样自定义局部钩子方法和全局钩子方法来实现自定义的校验规则。
- 如果不重写具体字段并设置validators属性的话,ModelForm是按照模型中字段的validators来校验的。
save()方法--添加、编辑
# 每个ModelForm还具有一个save()方法。 这个方法根据表单绑定的数据创建并保存数据库对象。
# ModelForm的子类可以接受现有的模型实例作为关键字参数instance;
# 如果提供此功能,则save()将更新该实例。
# 如果没有提供,save() 将创建模型的一个新实例。 >>> from myapp.models import Book
>>> from myapp.forms import BookForm # 根据POST数据创建一个新的form对象
>>> form_obj = BookForm(request.POST) # 创建书籍对象
>>> new_ book = form_obj.save() # 基于一个书籍对象创建form对象
>>> edit_obj = Book.objects.get(id=1)
# 使用POST提交的数据更新书籍对象
>>> form_obj = BookForm(request.POST, instance=edit_obj)
>>> form_obj.save()
11. modelform代码示例
view.py
def edit_book(request,n):
book_obj = models.Book.objects.filter(pk=n).first()
if request.method == 'GET':
# all_authors = models.Author.objects.all()
# all_publish = models.Publish.objects.all() form = BookForm(instance=book_obj) return render(request,'edit_book.html',{'form':form,'n':n})
# 传递的这个n参数是给form表单提交数据的是的action的url用的,因为它需要一个参数来识别是更新的哪条记录 else:
form = BookForm(request.POST,instance=book_obj)
# 必须指定instance,不然我们调用save方法的是又变成了添加操作
if form.is_valid():
form.save()
return redirect('show')
else:
return render(request,'edit_book.html',{'form':form,'n':n})
edit.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="{% static 'bootstrap-3.3.0-dist/dist/css/bootstrap.min.css' %}">
</head>
<body> <h1>编辑页面</h1>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<form action="{% url 'edit_book' n %}" novalidate method="post">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<label for="{{ field.id_for_label }}">{{ field.label }}</label>
{{ field }}
<span class="text-danger">{{ field.errors.0 }}</span>
</div>
{% endfor %} <div class="form-group">
<input type="submit" class="btn btn-primary pull-right">
</div>
</form>
</div>
</div>
</div> </body>
<script src="{% static 'bootstrap-3.3.0-dist/dist/jQuery/jquery-3.1.1.js' %}"></script>
<script src="{% static 'bootstrap-3.3.0-dist/dist/js/bootstrap.min.js' %}"></script>
</html> <!-- field.id_for_label 会和{{ field }}标签的id相同 -->
Django框架11 /form组件、modelForm组件的更多相关文章
- Django基础之Form和ModelForm组件
https://www.cnblogs.com/clschao/articles/10486468.html 1.创建django项目 2.创建py文件 3.导入form from django im ...
- Django框架 之 form组件
Django框架 之 form组件 浏览目录 Form介绍 普通的登录 使用form组件 Form详情 常用字段 校验 进阶 使用Django Form流程 一.Form介绍 我们之前在HTML页面中 ...
- Django之Form、ModelForm 组件
Django之Form.ModelForm 组件 一.Form组件: django框架提供了一个form类,来处理web开发中的表单相关事项.众所周知,form最常做的是对用户输入的内容进行验证,为此 ...
- Django框架 之 form组件的钩子
Django框架 之 form组件的钩子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 3 ...
- Django之Form与ModelForm组件
Django之Form与ModelForm组件 1.Form介绍 Form组件的主要功能如下: 生成页面可用的HTML标签 对用户提交的数据进行校验 O 保留上次的输入内容 普通方式手写注册功能 vi ...
- {Django基础十之Form和ModelForm组件}一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 ModelForm
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Model ...
- day 64 Django基础十之Form和ModelForm组件
Django基础十之Form和ModelForm组件 本节目录 一 Form介绍 二 Form常用字段和插件 三 From所有内置字段 四 字段校验 五 Hook钩子方法 六 进阶补充 七 Mod ...
- 第三百一十一节,Django框架,Form表单验证
第三百一十一节,Django框架,Form表单验证 表单提交 html <!DOCTYPE html> <html lang="en"> <head& ...
- Django框架 之 Form表单和Ajax上传文件
Django框架 之 Form表单和Ajax上传文件 浏览目录 Form表单上传文件 Ajax上传文件 伪造Ajax上传文件 Form表单上传文件 html 1 2 3 4 5 6 7 <h3& ...
随机推荐
- 一张图搞懂Ubuntu安装时姓名、计算机名、用户名
安装Ubuntu时会要求填写如下图的信息: 感谢:苏守坤 注意:上面的博客讲述了各自的具体含义,本篇博客只是说明这些名称在系统安装后会出现的位置.
- Flask 蓝图(Blueprint)使用方式解析
Flask蓝图提供了模块化管理程序路由的功能,使程序结构清晰.简单易懂.下面分析蓝图的使用方法 假如说我们要为某所学校的每个人建立一份档案,一个很自然的优化方式就是这些档案如果能分类管理,就是说假如分 ...
- TensorFlow从0到1之TensorFlow损失函数(12)
正如前面所讨论的,在回归中定义了损失函数或目标函数,其目的是找到使损失最小化的系数.本节将介绍如何在 TensorFlow 中定义损失函数,并根据问题选择合适的损失函数. 声明一个损失函数需要将系数定 ...
- (七)logback 异步输出日志
<!-- 异步输出 --> <appender name="ASYNC-INFO" class="ch.qos.logback.classic.Asyn ...
- java并发编程系列原理篇--JDK中的通信工具类Semaphore
前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ...
- Redis系列(五):数据结构List双向链表中基本操作操作命令和源码解析
1.介绍 List是通过ListNode实现的双向链表. 1.双端:获取某个结点的前驱和后继结点都是O(1) 2.无环:表头的prev指针和表尾的next指针都指向NULL,对链表的访问都是以NULL ...
- web scraper无法解决爬虫问题?通通可以交给python!
今天一位粉丝的需求所涉及的问题值得和大家分享分享~~~ 背景问题 是这样的,他看了公号里的关于web scraper的系列文章后,希望用它来爬取一个网站搜索关键词后的文章标题和链接,如下图 按照教程, ...
- Rigidbody(刚体)方法的初步学习(一)
概要:这次将简单的了解Rigidbody中的各种方法属性,以官方的API为顺序研究. 蛮牛API翻译:Rigidbody组件控制物体的位置—它使物体在重力影响下下落,并可计算物体将怎样响应碰撞.当操作 ...
- 容器技术之Docker Machine
前文我们聊了下docker容器的资源限制,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/13138725.html:今天我们来聊一聊docker machine ...
- PV、UV、VV、IP的区别
PV.UV.VV.IP的区别 PV即Page View,网站浏览量 指页面的浏览次数,用于衡量网站用户访问的网页数量.用户每次打开一个页面便记录1次PV,多次打开同一页面则浏览量累计. 一般来说,PV ...