「Django框架」-Form表单组件 django表格框架 table
myzbx 2024-12-22 19:43 53 浏览
文章来源于公众号【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野路子】
相关推荐
- 如何设计一个优秀的电子商务产品详情页
- 
        加入人人都是产品经理【起点学院】产品经理实战训练营,BAT产品总监手把手带你学产品电子商务网站的产品详情页面无疑是设计师和开发人员关注的最重要的网页之一。产品详情页面是客户作出“加入购物车”决定的页面... 
- 怎么在JS中使用Ajax进行异步请求?
- 
        大家好,今天我来分享一项JavaScript的实战技巧,即如何在JS中使用Ajax进行异步请求,让你的网页速度瞬间提升。Ajax是一种在不刷新整个网页的情况下与服务器进行数据交互的技术,可以实现异步加... 
- 中小企业如何组建,管理团队_中小企业应当如何开展组织结构设计变革
- 
        前言写了太多关于产品的东西觉得应该换换口味.从码农到架构师,从前端到平面再到UI、UE,最后走向了产品这条不归路,其实以前一直再给你们讲.产品经理跟项目经理区别没有特别大,两个岗位之间有很... 
- 前端监控 SDK 开发分享_前端监控系统 开源
- 
        一、前言随着前端的发展和被重视,慢慢的行业内对于前端监控系统的重视程度也在增加。这里不对为什么需要监控再做解释。那我们先直接说说需求。对于中小型公司来说,可以直接使用三方的监控,比如自己搭建一套免费的... 
- Ajax 会被 fetch 取代吗?Axios 怎么办?
- 
        大家好,很高兴又见面了,我是"高级前端进阶",由我带着大家一起关注前端前沿、深入前端底层技术,大家一起进步,也欢迎大家关注、点赞、收藏、转发!今天给大家带来的主题是ajax、fetch... 
- 前端面试题《AJAX》_前端面试ajax考点汇总
- 
        1.什么是ajax?ajax作用是什么?AJAX=异步JavaScript和XML。AJAX是一种用于创建快速动态网页的技术。通过在后台与服务器进行少量数据交换,AJAX可以使网页实... 
- Ajax 详细介绍_ajax
- 
        1、ajax是什么?asynchronousjavascriptandxml:异步的javascript和xml。ajax是用来改善用户体验的一种技术,其本质是利用浏览器内置的一个特殊的... 
- 6款可替代dreamweaver的工具_替代powerdesigner的工具
- 
        dreamweaver对一个web前端工作者来说,再熟悉不过了,像我07年接触web前端开发就是用的dreamweaver,一直用到现在,身边的朋友有跟我推荐过各种更好用的可替代dreamweaver... 
- 我敢保证,全网没有再比这更详细的Java知识点总结了,送你啊
- 
        接下来你看到的将是全网最详细的Java知识点总结,全文分为三大部分:Java基础、Java框架、Java+云数据小编将为大家仔细讲解每大部分里面的详细知识点,别眨眼,从小白到大佬、零基础到精通,你绝... 
- 福斯《死侍》发布新剧照 "小贱贱"韦德被改造前造型曝光
- 
        时光网讯福斯出品的科幻片《死侍》今天发布新剧照,其中一张是较为罕见的死侍在被改造之前的剧照,其余两张剧照都是死侍在执行任务中的状态。据外媒推测,片方此时发布剧照,预计是为了给不久之后影片发布首款正式预... 
- 2021年超详细的java学习路线总结—纯干货分享
- 
        本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础重点知识点:数据类型、核心语法、面向对象... 
- 不用海淘,真黑五来到你身边:亚马逊15件热卖爆款推荐!
- 
        Fujifilm富士instaxMini8小黄人拍立得相机(黄色/蓝色)扫二维码进入购物页面黑五是入手一个轻巧可爱的拍立得相机的好时机,此款是mini8的小黄人特别版,除了颜色涂装成小黄人... 
- 2025 年 Python 爬虫四大前沿技术:从异步到 AI
- 
        作为互联网大厂的后端Python爬虫开发,你是否也曾遇到过这些痛点:面对海量目标URL,单线程爬虫爬取一周还没完成任务;动态渲染的SPA页面,requests库返回的全是空白代码;好不容易... 
- 最贱超级英雄《死侍》来了!_死侍超燃
- 
        死侍Deadpool(2016)导演:蒂姆·米勒编剧:略特·里斯/保罗·沃尼克主演:瑞恩·雷诺兹/莫蕾娜·巴卡林/吉娜·卡拉诺/艾德·斯克林/T·J·米勒类型:动作/... 
- 停止javascript的ajax请求,取消axios请求,取消reactfetch请求
- 
        一、Ajax原生里可以通过XMLHttpRequest对象上的abort方法来中断ajax。注意abort方法不能阻止向服务器发送请求,只能停止当前ajax请求。停止javascript的ajax请求... 
- 一周热门
- 最近发表
- 标签列表
- 
- 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 轮廓宽度 (31)
- CSS 谷歌字体 (33)
- CSS 链接 (31)
- CSS 定位 (31)
- CSS 图片库 (32)
- CSS 图像精灵 (31)
- SVG 文本 (32)
- 时钟启动 (33)
- HTML 游戏 (34)
- JS Loop For (32)
 
