「Django框架」-Form表单组件 django表格框架 table
myzbx 2024-12-22 19:43 16 浏览
文章来源于公众号【Python野路子】
HTML表单是网站交互性的经典方式,本章将记录如何用Django对用户提交的表单数据进行处理。
HTML中的表单
站在前端角度,form表单是HTML中用于提交数据给服务器的一个标签,所有的表单元素(input/textarea/button...)都要放在form标签当中,还有以下参数:
- form的method参数用于设置表单的提交方式,默认使用GET;
- action用于设置表单的提交url,如果不写或者保持空字符串,那么将使用当前的URL,建议尽量指定一个url,因为有些浏览器可能兼容问题,不填是不能获取到对应的action的。
Django中的表单
Django中的表单不是html中的那个表单,这里是指Django中的组件名叫表单,主要做以下2件事:
1)表单验证数据的合法性。
2)通渲染表单模板;
Form
Form类在from django import forms中,使用时需要定义一个Form的子类,相当于将请求的表单数据封装到一个特殊的类中,并自动完成一些数据的验证工作。
Form基本使用
1)先在某个应用app下,新建一个forms.py的文件(类似前面学过的views.py和urls.py在对应app应用下)。
2)在里面定义一个表单类,继承自django.forms.Form
from django import forms
3)在表单类中,创建字段与模型类类似,但是没有null=True(是否接受空值NULL,默认值False)或者blank=True(是否接受空白内容,默认为False)等这几种参数了,有的参数是required=True/False(请求能否为空,True不能为空,默认为True)。
from django import forms
class RegisterForm(forms.Form):
# label属性是form表单中特有的属性,代表这个字段的描述,这个属性类似于模型类中的verbose_name属性
username = forms.CharField(label=u'用户名', max_length=20, min_length=3)
# 存储到数据库的密码,是一个加密后的字符串,但是这里是通过前端传输过来的,并没进行加密
password = forms.CharField(label=u'密码', max_length=20, min_length=8)
4)表单生成HTML表单元素。
# views.py
class RegisterView(View):
def get(self, request):
# 如果需要使用django表单渲染html页面
# 实例化该表单模型,传递给前端
form = RegisterForm()
return render(request, 'register_form.html', {'form': form})
def post(self, request):
# 如果不使用django表单,需要一个一个的值取出来,并且需要自己写对应的验证
username = request.POST.get('username')
password = request.POST.get('password')
return render(request, 'register_form.html', locals())
<!-- register_form.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
{% if username %}
提交的post数据:
{{ username }}
{{ password }}
{% else %}
<form action = "{% url "user:register" %}" method="post">
{% csrf_token %}
{{ form }} <!--会自动识别表单属性的 -->
<input type="submit" vlaue='注册'>
</form>
{% endif %}
</body>
</html>
注意:使用Django的Form类生成的表单,不包含form和submit按钮两个标签,需要手动添加。
一般用于生成HTML表单元素很少使用,尤其在现在前后分离趋势下,这个功能很鸡肋,把前端该做的事情放到后台来实现,增加了代码的耦合性,也增加了服务器的压力。
我们一般使用forms组件的校验功能,比如账号长度必须6~12位,密码长度必须为8~20位,且必须含大小写字母,我们可以一个个获取前端传过来的字段进行一个个校验,如果字段比较多,如果一个个单独校验,那比较繁琐,那我们可以使用django提供的forms组件,我们先来看个简单的。
# forms.py
'''
forms.py的作用
它是专门编写你的forms配置的模型
forms.py本身命名没有要求,你可以为任意名称, 但是我们一般约定它叫forms,代表这个文件是专门处理该APP下处理表单组件的
'''
from django import forms
class RegisterForm(forms.Form):
username = forms.CharField(max_length=20, min_length=3)
password = forms.CharField(max_length=20, min_length=8)
# views.py
class RegisterView(View):
def get(self, request):
# 如果需要使用django表单渲染html页面
# 实例化该表单模型,传递给前端
form = RegisterForm()
return render(request, 'register_form.html', {'form': form})
def post(self, request):
# 满足Form里面
form = RegisterForm({'username': 'admin', 'password': '12345678'})
print(form.is_valid()) # True
print(form.cleaned_data) # {'username': 'admin', 'password': '12345678'},输出全部校验正确的字段
print(form.errors)
# 其中一个不满足,例如密码长度少于8
form = RegisterForm({'username': 'admin', 'password': '12345'})
print(form.is_valid()) # False
print(form.cleaned_data) # {'username': 'admin'}, 输出校验正确的字段
print(form.errors)
'''
<ul class="errorlist">
<li>password
<ul class="errorlist">
<li>Ensure this value has at least 8 characters (it has 5).</li>
</ul>
</li>
</ul>
'''
print(type(form.errors)) # <class 'django.forms.utils.ErrorDict'>
print(form['password'].errors)
# <ul class="errorlist"><li>Ensure this value has at least 8 characters (it has 5).</li></ul>
print(form.errors.get('password'))
# <ul class="errorlist"><li>Ensure this value has at least 8 characters (it has 5).</li></ul>
print(form.errors.get_json_data())
# {'password': [{'message': 'Ensure this value has at least 8 characters (it has 5).', 'code': 'min_length'}]}
# 比Form少一个字段
form = RegisterForm({'username': 'admin'})
print(form.is_valid()) # False
print(form.cleaned_data) # {'username': 'admin'}
print(form.errors)
'''
<ul class="errorlist">
<li>password
<ul class="errorlist">
<li>This field is required.</li>
</ul>
</li>
</ul>
'''
print(form.errors.get('password'))
# <ul class="errorlist"><li>This field is required.</li></ul>
print(form.errors.get_json_data())
# {'password': [{'message': 'This field is required.', 'code': 'required'}]}
# 比Form多一个字段,例如多个age
form = RegisterForm({'username': 'admin', 'password': '12345678', 'age': 18})
print(form.is_valid()) # True
print(form.cleaned_data) # {'username': 'admin', 'password': '12345678'}, 比Form多的字段不输出
print(form.errors)
return render(request, 'register_form.html', locals())
我们这里先传几个固定的参数来进行测试,通过上面测试,我们可以总结下。
1)使用is_valid()方法可以验证用户提交的数据是否合法,这个方法会返回一个bool值,合法则返回True,否则返回False。其中在实例化一个form对象时,传的参数必须与Form里面定义的字段:
- 传的字段名一样;
- 字段值必须满足Form里面的校验规则;
- 传的参数个数 等于或大于 Form定义的个数。
2)cleaned_data()获取满足Form校验规则的字段, 使用cleaned_data必须执行完is_valid()方法。
3)如果表单校验没有通过,form对象则会产生一个errors属性,这个属性包括所有的验证错误信息。我们可以获取错误信息传递给前端。
- form.errors:这个属性获取的错误信息是一个包含html标签的错误信息。
- 通过form['属性名'].erros或form.errors.get('属性名')访问对应的错误。
- 通过form.errors.get_json_data()或form['属性名'].erros.get_json_data()可以将错误消息转换成JSON数据。
- 默认的错误信息是英文不够人性化,我们可以通过在Field中添加一个error_messages的dict类型的参数,然后根据属性名设置对应的message,例如以下代码:password = forms.CharField(label=u'密码', max_length=20, min_length=8, error_messages={'required':u'密码不能为空'})
必须要执行完is_valid函数,否则errors是不会包含错误。
常用Field字段
在表单中,创建字段跟模型是一模一样的,但是没有null=True(是否接受空值NULL,默认值False)或者blank=True(是否接受空白内容,默认为False)等这几种参数了,有的参数是required=True/False(请求能否为空,True不能为空,默认为True)。
使用Field可以是对数据验证的第一步。你期望这个提交上来的数据是什么类型,那么就使用什么类型的Field。
CharField
用来接收文本。参数:
- max_length:这个字段值的最大长度。
- min_length:这个字段值的最小长度。
- required:这个字段是否是必须的。默认是True,必须的。
- error_messages:字段验证失败时给出的错误提示信息,需要传入一个字典,字典中需要指定对应验证条件的错误提示信息,如error_messages={'max_length': '最多只能有100个字符!'}表示指定文本最大长度不满足时给出提示信息。
EmailField
用来接收邮件,会自动验证邮箱格式是否合法。错误信息的key:required、invalid。
FloatField
用来接收浮点类型,并且如果验证通过后,会将这个字段的值转换为浮点类型。参数:
- max_value:最大的值。
- min_value:最小的值。
错误信息的key:required、invalid、max_value、min_value。
IntegerField
用来接收整形,并且验证通过后,会将这个字段的值转换为整形。参数:
- max_value:最大的值。
- min_value:最小的值。
错误信息的key:required、invalid、max_value、min_value。
URLField
用来接收url格式的字符串。错误信息的key:required、invalid。
FileField
用来接收文件,allow_empty_file=False是否允许空文件。
ImageField
接收图片,注意需要PIL模块,pip3 install Pillow,以上2个字典使用时,需要注意2点:
- form表单中enctype="multipart/form-data"
- view函数中my_form= MyForm(request.POST, request.FILES)
验证器
Form类中的各个Field字段其实都有一些基本的验证器,如果表单中的某个字段想要额外添加一些验证功能,可以指定validators参数给字段添加一些验证器,或者给这个字段定义一个额外的形如clean_[字段名]自定义验证方法。
内置验证器
内置验证器通过字段的validators参数指定对应的验证器列表即可,Django内置的验证器都在django.core.validators中,常用的内置验证器:
- MaxValueValidator:最大值。
- MinValueValidator:最小值。
- MaxLengthValidator:最大长度。
- MinLengthValidator:最小长度。
- EmailValidator:是否为邮箱格式。
- URLValidator:是否为url格式。
- RegexValidator:是否符合正则表达式,使用时传入一个正则表达式即可。
- FileExtensionValidator:验证文件名后缀是否符合要求,使用时传入一个文件名后缀的列表,如['txt', 'csv'],表示只允许上传这些类型的文件。
自定义验证
系统自带表单校验规则,有时无法满足我们的需求,比如在注册的表单验证中,我们需要验证用户是否已经被注册过了,那么这个时候就需要去数据库查询判断才知道,这个时候我们可以对某个字段,进行自定义的验证。
需要针对某个字段进行特殊验证时,可以在Form表单类中定义一个clean_[字段名]的方法,就会自动执行这个方法进行验证了,如果不符合要求,直接抛出异常即可,符合要求则返回对应的值。如果想要针对多个字段之间的验证,可以重写clean()方法,当所有字段的验证都通过后就会执行这个方法。
# form.py
from django import forms
from .models import Account
class RegisterForm(forms.Form):
# label 属性是form表单中特有的属性,代表这个字段的描述,这个属性类似于模型类中的verbose_name属性
username = forms.CharField(label=u'用户名', min_length=3, max_length=18,
error_messages={'required': u'用户名不能为空',
'min_length': u'用户名不少于3位',
'max_length': u'用户名不超过18位'
})
password = forms.CharField(label=u'密码', required=True, min_length=6, max_length=16,
error_messages={'required': u'密码不能为空', 'min_length': u'密码不少于6位',
'max_length': u'密码不超过16位'})
confirm_pwd = forms.CharField(label=u'确认密码', min_length=6, max_length=16,
error_messages={'required': u'确认密码不能为空', 'min_length': u'密码不少于6位',
'max_length': u'密码不超过16位'})
# 可以不填
email = forms.EmailField(label=u'邮箱', required=False) # required 请求能否为空,True不能为空,默认为True
# 表单自定义错误消息:重写方法clean_field(field是一个属性名),可以自定义针对某一个field的验证机制,一个属性一个对应方法
# clean() 或者 clean_xxx() 会在执行 form.is_valid() 的过程中被调用
def clean_username(self):
# 当字段的基本验证通过后,会将数据存储在cleaned_data中
username = self.cleaned_data['username']
if Account.objects.filter(username=username).exists():
# 如果这里判断有多个错误存在,则使用add_error方法。
self.add_error('username', '该用户名已使用,请重新选择!')
# 如果只是单个错误,使用ValidationError,否则这里raise抛出去了,后面就不能执行了
#raise forms.ValidationError('用户已存在')
# 敏感词汇
if username.find('mmp') >= 0:
self.add_error('username', '存在敏感字符')
# 需要返回处理后的值
return username
def clean_confirm_pwd(self): #不能用clean_password,因为加载这个时候,confirm_pwd还没加载出来,是没有值的。
pwd = self.cleaned_data['password']
confirm_pwd = self.cleaned_data['confirm_pwd']
if pwd != confirm_pwd:
raise forms.ValidationError('两次密码不一致', code='')
return pwd
def clean(self):
# 执行这个方法时表示所有字段都已验证成功,当然,需要先调用父类的clean()方法
cleaned_data = super().clean()
# 当字段的基本验证通过后,会将数据存储在cleaned_data中
# 获取需要验证的字段
...
# 需要返回处理后的值
return cleaned_data
def get_error_dict(self):
# 提取错误信息
if hasattr(self, 'errors'): #hasattr() 函数用于判断对象是否包含对应的属性。
errors = self.errors.get_json_data()
print(type(errors)) # <class 'dict'>
print(errors)
# {'username': [{'message': '用户名不能为空', 'code': 'required'}],
# 'password': [{'message': '密码不能为空', 'code': 'required'}],
# 'confirm_pwd': [{'message': '确认密码不能为空', 'code': 'required'}]}
err_msg_dict = {}
for key, message in errors.items():
print(key, message) # username [{'message': '用户名不能为空', 'code': 'required'}]
msg_list = []
for msg in message:
print(msg) # {'message': '用户名不能为空', 'code': 'required'}
msg_list.append(msg['message'])
err_msg_dict[key] = msg_list
print(err_msg_dict) # {'username': ['用户名不能为空'], 'password': ['密码不能为空'], 'confirm_pwd': ['确认密码不能为空']}
return err_msg_dict
return None
def get_error_str(self):
# 提取错误信息
if hasattr(self, 'errors'): #hasattr() 函数用于判断对象是否包含对应的属性。
errors = self.errors.get_json_data().values() # 获取字典值部分
print(errors)
#dict_values([[{'message': '用户名不能为空', 'code': 'required'}],
# [{'message': '密码不能为空', 'code': 'required'}], [{'message': '确认密码不能为空', 'code': 'required'}]])
err_msg_list = []
for itme in errors:
print(itme) # [{'message': '用户名不能为空', 'code': 'required'}]
err_msg_list.append(itme[0].get('message'))
print(err_msg_list) # ['用户名不能为空', '密码不能为空', '确认密码不能为空']
err_msg_str = ';'.join(err_msg_list) # 将错误信息通过;拼接成字符串
print(err_msg_str) # 用户名不能为空;密码不能为空;确认密码不能为空
return err_msg_str
return None
视图views.py
class RegisterView(View):
def get(self, request):
# 如果需要使用django表单渲染html页面
# 实例化该表单模型,传递给前端
return render(request, 'register_form.html')
def post(self, request):
print(request.POST) #<QueryDict: {'username': ['admin'], 'password': ['6666'], 'confirm_pwd': ['222'], 'email': ['']}>
register_form = RegisterForm(request.POST)
if register_form.is_valid():
# 使用cleaned_data 必须执行完is_valid 且返回为True才能获取数据,保存用户提交上来的数据
print(register_form.cleaned_data)
username = register_form.cleaned_data['username']
password = register_form.cleaned_data['password']
# 利用字典解包方式
params = {'username': username, 'password': password}
Account.objects.create(**params)
return HttpResponse('注册成功')
else:
print(register_form.errors)
# <ul class="errorlist"><li>username<ul class="errorlist"><li>用户名不能为空</li></ul></li></ul>
print(register_form.errors.get_json_data())
# {'username': [{'message': '用户名不能为空', 'code': 'required'}]}
print(register_form.errors.get('username')) # <ul class="errorlist"><li>用户名不能为空</li></ul>
print(register_form.errors.get('username').get_json_data()) # [{'message': '用户名不能为空', 'code': 'required'}]
err_msg_dict = register_form.get_error_dict()
# {'username': ['用户名不能为空'], 'password': ['密码不能为空'], 'confirm_pwd': ['确认密码不能为空']}
return render(request, 'register_form.html', err_msg_dict)
模板register_form.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url "user:register" %}" method="post">
用户名:<input type="text" name="username"><span>{{ username.0 }}</span>
密 码:<input type="password" name="password"><span>{{ password.0 }}</span>
确认密码:<input type="password" name="confirm_pwd"><span>{{ confirm_pwd.0 }}</span>
邮 箱:<input type="email" name="email">
<input type="submit" vlaue='注册'>
</form>
</body>
</html>
自定义错误信息,可以通过在定义表单类是设置相关属性,校验不通过则会报默认错误。我们可以通过设置error_messages字典来设置对应message。也可以自定义错误信息。
不管那种必须要执行完is_valid函数,否则执行相关errors是不会包含错误,form类的运行顺序是init,clean,validte,save,如果遇到类似错误,比如说不能为空,最大最小长度时,在error_messages写了错误信息,也自定义了表单错误信息,则required=True时调用error_message,否则自定义的。
ModelForm
通过上面我们发现,Form表单中的字段与模型中的字段基本是一模一样的,表单中需要验证的数据,也就是模型中需要保存的,我们可以将模型中的字段与表单中的字段进行绑定,例如上面RegisterForm改成继承forms.ModelForm。
# models.py
class Account(models.Model):
username = models.CharField(max_length=16)
password = models.CharField(max_length=20)
class Meta:
db_table = 'tb_account'
def __str__(self):
return self.username
# forms.py
class RegisterForm(forms.ModelForm):
"""
1.补充 Model 没有的 Field 到表单,例如这里的confirm_pwd
2.覆盖 Model 中的 Field 定义
"""
confirm_pwd = forms.CharField(label=u'确认密码', min_length=6, max_length=16,
error_messages={'required': u'确认密码不能为空', 'min_length': u'密码不少于6位', 'max_length': u'密码不超过16位'})
class Meta:
model = Account # 对应model中的类
fields = '__all__' # 说明要关联类中的哪些字段,默认__all__关联所有字段,如果不需要全部
# exclude = ['avatar'] # 排除字段
error_messages = { # 自定义错误信息
'username': {
'max_length': '用户名长度不超过16位',
'required': "用户名不能为空",
},
'password': {
'max_length': '用户名长度不超过16位',
'required': "用户名不能为空",
}
}
def clean_confirm_pwd(self):
pwd = self.cleaned_data['password']
confirm_pwd = self.cleaned_data['confirm_pwd']
if pwd != confirm_pwd:
raise forms.ValidationError('两次密码不一致', code='')
return pwd
# views.py
from .forms import RegisterForm
from hashlib import md5
class RegisterView(View):
def get(self, request):
# 如果需要使用django表单渲染html页面
# 实例化该表单模型,传递给前端
return render(request, 'register_form.html')
def post(self, request):
print(request.POST)
register_form = RegisterForm(request.POST)
if register_form.is_valid():
# 使用cleaned_data 必须执行完is_valid 且返回为True才能获取数据,保存用户提交上来的数据
print(register_form.cleaned_data)
# {'username': 'admin666', 'password': '1q2w3e4r', 'confirm_pwd': '1q2w3e4r'}
register_form.save() # 这里save即使多了个confirm_pwd没关系,是按照model字段来的。
return HttpResponse('注册成功')
else:
print(register_form.errors.get_json_data())
#{'username': [{'message': '用户名不能为空', 'code': 'required'}],
# 'password': [{'message': '用户名不能为空', 'code': 'required'}],
# 'confirm_pwd': [{'message': '确认密码不能为空', 'code': 'required'}]}
print(register_form.errors.get('username').get_json_data()) # [{'message': '用户名不能为空', 'code': 'required'}]
return render(request, 'register_form.html')
RegisterForm是继承自forms.ModelForm,然后在表单中定义了一个Meta类,在Meta类中指定了model=Account,以及fields="__all__",这样就可以将Account模型中所有的字段都复制过来,进行验证。如果只想针对其中几个字段进行验证,那么可以给fields指定一个列表,将需要的字段写进去。
如果要验证的字段比较多,只是除了少数几个字段不需要验证,那么可以使用exclude来代替fields。
与普通的Form表单验证类型类似,ModelForm表单的验证在调用is_valid()或访问errors属性时隐式调用。
验证时,可以在ORM模型的字段定义中指定validators参数,添加额外的验证器即可。
自定义错误,因为字段都不是在表单中定义的,而是在模型中定义的,因此一些错误消息无法在字段中定义。那么这时候可以在Meta类中,定义error_messages,然后把相应的错误消息写到里面去。
自定义校验规则与Form表单一样。
save保存,ModelForm还有save方法,可以在验证完成后直接调用save方法,就可以将这个数据保存到数据库中了。这个方法必须要在clean没有问题后才能使用,如果在clean之前使用,会抛出异常。另外,我们在调用save方法的时候,如果传入一个commit=False,那么只会生成这个模型的对象,而不会把这个对象真正的插入到数据库中。比如表单上验证的字段没有包含模型中所有的字段,这时候就可以先创建对象,再根据填充其他字段,把所有字段的值都补充完成后,再保存到数据库中,例如:
form = MyForm(request.POST)
if form.is_valid():
article = form.save(commit=False)
article.category = 'Python'
article.save()
return HttpResponse('succes')
else:
print(form.get_errors())
return HttpResponse('fail')
并且即使form的数据比model模型字段多也没关系。
ModelForm的子类可以接受现有的模型实例作为关键字参数instance;如果提供此功能,则save()将更新该实例。如果没有提供,save() 将创建模型的一个新实例。
# 修改表数据是,记得把instance信息也传进去,不然是新建数据,而不是对某行数据进行修改。
article_form = ArticleAddForm(dict_data, instance=article) # 指定给谁做修改
if article_form.is_valid():
article_form.save()
return json_status.result(message='文章更新成功')
文章来源于公众号【Python野路子】
相关推荐
- 批量将 Word 转换为 PDF/Excel/Txt/图片等多种格式
-
Word文档是我们工作中经常会打交道的一种文档格式,我们也经常会有需要对Word文档进行格式转换的需求,比如将Word格式转换为PDF、将Word文档转换为Excel、将Word...
- 绝了!一键用AI生成高颜值动态PPT(附详细步骤+Prompt)
-
大家好,我是一名酷爱研究AI的产品经理,最近我有个新发现:那些花了你3天做出来的PPT,现在用AI可以1小时搞定!而且颜值还高!为什么AI做PPT比传统方式效率高10倍?我用一张图就能告诉你:AI生成...
- ztext - 简单几行代码创建酷炫3D特效文字的开源JS库
-
把网页上的文字变成酷炫的3D风格,还能制作旋转动效,有了ztext.js,只需要几行代码。ztext能做什么ztext.js是一个能把常规的平面文字变成3D样式的前端开源代码库,让开发者...
- 文字内插入小图片,也太可爱了吧(文字中怎么插图片)
-
图文排版H5手机版秀米有小伙伴留言问添加图片的时候可不可以把图片添加到文字之间比如下面这句话中的小贴纸图片后面可以接着输入文字其实吧这就是咱们的『文字内插入小图片』功能嘛可以用来在文字内加个表情包又...
- Linux环境下C++代码性能分析方法(linux怎么写c++代码)
-
技术背景在开发C++应用程序时,找出代码中运行缓慢的部分是进行性能优化的关键。在Linux系统上,有多种工具和方法可用于对C++代码进行性能分析,每种方法都有其特点和适用场景。实现步骤手动中断调试法在...
- SVG互动图文,让你的文章更有趣!教你4种简单易学的黑科技玩法!
-
如果你是一个公众号创作者,那么你一定想知道如何让你的文章更加吸引人,更加有趣,更加有创意。你可能已经尝试过各种图文排版技巧,但是你是否知道,有一种黑科技可以让你的文章变得更加酷炫,更加互动,更加爆款?...
- Videoscribe怎么实现实心中文汉字的手绘制作
-
很多朋友在制作手绘视频的时候,不知道怎么输入实心的中文汉字,之前我们已经给大家分享了怎么输入汉字的方法,但是有一点遗憾的是输出的汉字是空心的手绘展示,在视觉上并不是非常的美观。经过大家不断的探索,终于...
- 一款用于将文本转化成图表的现代化脚本语言
-
大家好,又见面了,我是GitHub精选君!今天要给大家推荐一个GitHub开源项目terrastruct/d2,该项目在GitHub有超过10.3kStar,用一句话介绍该项目就是:...
- 探秘 Web 水印技术(制作水印网站)
-
作者:fransli,腾讯PCG前端开发工程师Web水印技术在信息安全和版权保护等领域有着广泛的应用,对防止信息泄露或知识产品被侵犯有重要意义。水印根据可见性可分为可见水印和不可见水印(盲水印)...
- 不忍心卸载的五款神仙工具(不忍心卸载的五款神仙工具是什么)
-
001.效率工具uTools-装机必备的生产力工具集uTools是一款非常强大的可以装下几乎所有效率工具的电脑生产力工具集,目前拥有Windows、Mac和Linux三个版本。软件界面...
- 「SVG」飞花令!这份最高检工作报告“超有料”
-
原标题:【SVG】飞花令!这份最高检工作报告“超有料”栏目主编:秦红文字编辑:沈佳灵来源:作者:最高人民检察院...
- svg|2025政府工作报告,有没有你关心的数据?
-
··<setattributeName="visibility"begin="click+0s"dur="1ms"fill="freeze"restart="never"to="hi...
- videoscribe只能输入英文,如何输入中文文本?
-
videoscribe只能输入英文,如何输入中文文本?打开VideoScribe软件,打开要添加中文字体的位置。打开Photoshop并在文件中创建一个新的透明背景图层。注意:必须是透明背景层。...
- 五个流行的SVG在线编辑器(svg编辑工具)
-
随着响应网络的发展,越来越多的高质量的SVG在线编辑器被公众所熟知。SVG矢量图形也越来越受欢迎,以便在任何设备上呈现图像,甚至一些易于使用的SVG在线编辑器,可以替代PS,本文总结了五种流行的SVG...
-
- 手绘视频-videoscribe怎么输入中文
-
videoscribe软件本身不能输入中文,可借助辅助软件inkscape或者AI等矢量软件实现今天以inkscape这款软件来讲解,相关软件下载可到小林课堂微信公众号(xiaolinketang)回复关键字“辅助工具”进行下载操作步骤如...
-
2025-04-30 18:21 myzbx
- 一周热门
- 最近发表
- 标签列表
-
- HTML 简介 (30)
- HTML 响应式设计 (31)
- HTML URL 编码 (32)
- HTML Web 服务器 (31)
- HTML 表单属性 (32)
- HTML 音频 (31)
- HTML5 支持 (33)
- HTML API (36)
- HTML 总结 (32)
- HTML 全局属性 (32)
- HTML 事件 (31)
- HTML 画布 (32)
- HTTP 方法 (30)
- 键盘快捷键 (30)
- CSS 语法 (35)
- CSS 选择器 (30)
- CSS 轮廓 (30)
- CSS 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 中级教程 (30)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (31)