2024--Django平台开发-Django知识点(六)

day06 Django知识点

今日概要:

  • Form和ModelForm组件【使用】【源码】
  • 缓存【使用】
  • ORM【使用】
  • 其他:ContentTypes、Admin、权限、分页、信号等

1.Form和ModelForm组件

背景:某个公司后台管理项目。

  • 垃圾

    def register(request):""" 用户注册 """# 1.获取提交数据mobile = request.POST.get("mobile")sms = request.POST.get("sms")name = request.POST.get("name")age = request.POST.get("age")email = request.POST.get("email")password = request.POST.get("password")# 2.校验判断(10行)# all([mobile,sms])# 正则表达式# 3.业务逻辑代码
    
  • 框架(内置+第三方表单验证组件)

    <form method="post"><input type="text" name="mobile1" />{{form.mobile1}}<input type="text" name="sms" />{{form.sms}}<input type="submit" value="提交" />
    </form>
    
    class MyForm(Form):mobile1 = forms.CharField(reg="\d{11}", required=True)sms = forms.CharField(required=True)def register(request):""" 用户注册 """if request.method == "GET":# form = MyForm(instance={"mobile1":"18766666666","sms":"999"})form = MyForm()return render(request, "xxxxx.html",{"form":form})# 1.获取提交数据form = MyForm(request.POST)if form.is_valid():print(form.cleared_data)else:print(form.errors)# 3.业务逻辑代码return render(request, "xxxxx.html",{"form":form})
    

关于组件:表单验证、自动生成HTML标签、数据初始化(新建按钮、编辑按钮)、保持原来的数据。

1.1 初识Form组件

基于注册为例来进行测试。

详细见示例:1-form组件.zip

1.2 错误信息

在这里插入图片描述

1.3 展示所有的字段

对象和可迭代对象。

在这里插入图片描述

1.4 问题:关于样式

  • 手动操作

    class RegisterForm(forms.Form):v1 = forms.CharField(label="手机号",required=True,# max_length=19,# min_length=6,initial="武沛齐",validators=[RegexValidator(r'^\d{11}$', "手机号格式错误"), ],widget=forms.TextInput(attrs={"class":"form-control"}) # <input type="text" class="form-control"/>)v2 = forms.CharField(label="备注",required=True,widget=forms.Textarea(attrs={"class":"form-control"}) # <textarea class="form-control"/></textarea>)............
    
    {% for field in form %}<p>{{ field.label }} {{ field }} {{ field.errors.0 }}  </p>
    {% endfor %}
    
  • 自动操作(找到每个字段中的widget插件,再找到插件中的attrs属性,给他每个赋值**{“class”:“form-control”}**

    class RegisterForm(forms.Form):v1 = forms.CharField(...,widget=forms.TextInput)v2 = forms.CharField(...,widget=forms.TextInput(attrs={"v1":"123"}))def __init__(self,*args,**kwargs):super().__init__(self,*args,**kwargs)for name,field in self.fields.items():if name == "v1":continue if field.widget.attrs:field.widget.attrs.update({"class":"form-control"})else:field.widget.attrs = {"class":"form-control"}
    
    form = RegisterForm()                   # __init__
    form = RegisterForm(data=request.POST)  # __init__
    

1.5 问题:通用父类

class BootStrapForm(object):def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)for name, field in self.fields.items():field.widget.attrs = {"class": "form-control"}class LoginForm(BootStrapForm, forms.Form):user = forms.CharField(label="用户名", widget=forms.TextInput)pwd = forms.CharField(label="密码", widget=forms.TextInput)def login(request):form = LoginForm()return render(request, "login.html", {"form": form})
class BootStrapForm(forms.Form):def __init__(self, *args, **kwargs):# 不是找父类# 根据类的mro(继承关系),去找上个类# super().__init__(*args, **kwargs)for name, field in self.fields.items():field.widget.attrs = {"class": "form-control"}class LoginForm(BootStrapForm):user = forms.CharField(label="用户名", widget=forms.TextInput)pwd = forms.CharField(label="密码", widget=forms.TextInput)def login(request):form = LoginForm()return render(request, "login.html", {"form": form})

1.6 答疑

类的内部继承关系,是继续c3算法。

class A:passclass B:passclass C(B,A):pass# [<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
print(C.mro())
老师 假如我们通过继承BootStrapForm实现批量给field对象添加{'class': 'form-control'}属性,那还能添加判断是否存在属性,若存在则更新;不存在再进行添加吗

1.7 ModelForm

  • 使用Form

    • 创建Form类 + 定义字段

      class LoginForm(forms.Form):user = forms.CharField(label="用户名", widget=forms.TextInput)pwd = forms.CharField(label="密码", widget=forms.TextInput)
      
    • 视图

      def login(request):if request.method == "GET":form = LoginForm()return render(request, "login.html", {"form": form})form = LoginForm(data=request.POST)if not form.is_valid():# 校验失败return render(request, "login.html", {"form": form})print(form.cleaned_data)# ...return HttpRespon("OK")
      
    • 前端

      <form>{% for field in form %}<p>{{ field.label }} {{ field }} {{ field.errors.0 }}</p>{% endfor %}
      </form>
      
  • 使用ModelForm

    • models.py

      class UserInfo(models.Model):name = models.CharField(verbose_name="用户名", max_length=32)age = models.IntegerField(verbose_name="年龄")email = models.CharField(verbose_name="邮箱", max_length=128)
      
    • 创建ModelForm

      class LoginForm(forms.ModelForm):mobile = forms.CharFiled(label="手机号")class Meta:model = models.UserInfofileds = ["name","age", "mobile"]
      
    • 视图使用

      def login(request):form = LoginModelForm()return render(request, "login.html", {"form": form})
      
    • 页面

      <form>{% for field in form %}<p>{{ field.label }} {{ field }} {{ field.errors.0 }}</p>{% endfor %}
      </form>
      

    注意:

    • 后续进行增伤改查是基于数据库Models中的某个表,推荐使用:ModelForm;

    • 如果要进行表单校验是与数据库的表无关直接使用Form。

1.8 ModelForm两个好的地方

1.8.1 初始化数据

  • Form

    class LoginForm(BootStrapForm, forms.Form):user = forms.CharField(label="用户名", widget=forms.TextInput)pwd = forms.CharField(label="密码", widget=forms.TextInput)
    
    def login(request):form = LoginForm(initial={"user": "武沛齐", "pwd": "123"})return render(request, "login.html", {"form": form})
    

    在这里插入图片描述

  • ModelForm

    class LoginModelForm(BootStrapForm, forms.ModelForm):mobile = forms.CharField(label="手机号", widget=forms.TextInput)class Meta:model = models.UserInfofields = ["name", "age", "mobile"]widgets = {"age": forms.TextInput,}labels = {"age": "x2",}def clean_name(self):value = self.cleaned_data['name']# raise ValidationError("....")return value
    
    def login(request):user_object = models.UserInfo.objects.filter(id=1).first()form = LoginModelForm(instance=user_object, initial={"mobile": "武沛齐"})return render(request, "login.html", {"form": form})
    

在这里插入图片描述

1.8.2 新建数据

  • Form组件

    def login(request):if request.method == "GET":form = LoginForm(initial={"user": "武沛齐", "pwd": "123"})return render(request, "login.html", {"form": form})form = LoginForm(data=request.POST)if not form.is_valid():return render(request, "login.html", {"form": form})# form.cleaned_data# 手动读取字典,保存至数据库# models.UserInfo.objects.create(name=form.cleaned_data['xx'], pwd=form.cleaned_data['yy'])return HttpResponse("成功")
    
  • ModelForm组件

    def login(request):if request.method == "GET":form = LoginForm()return render(request, "login.html", {"form": form})form = LoginForm(data=request.POST)if not form.is_valid():return render(request, "login.html", {"form": form})form.save() # 自动将数据新增到数据库return HttpResponse("成功")
    

1.8.3 更新数据

  • Form组件

    def login(request):if request.method == "GET":form = LoginForm(initial={"user": "武沛齐", "pwd": "123"})return render(request, "login.html", {"form": form})form = LoginForm(data=request.POST)if not form.is_valid():return render(request, "login.html", {"form": form})# form.cleaned_data# 手动读取字典,保存至数据库# models.UserInfo.objects.create(name=form.cleaned_data['xx'], pwd=form.cleaned_data['yy'])# models.UserInfo.objects.filter(id=1).update(name=form.cleaned_data['xx'], pwd=form.cleaned_data['y'])return HttpResponse("成功")
    
  • ModelForm组件

    def login(request):if request.method == "GET":form = LoginModelForm()return render(request, "login.html", {"form": form})user_object = model.UserInfo.object.filter(id=1).first()form = LoginModelForm(data=request.POST, instance=user_object)if not form.is_valid():return render(request, "login.html", {"form": form})form.save() # 更新id=1return HttpResponse("成功")
    

1.9 案例

  • 用户登录【Form】
  • 用户管理:增改【ModelForm】

2.Form相关源码

2.1 前置知识点

1.模板渲染

def login(request):# 1.打开login2.html文件读取内容 + 参数进行“替换” => 渲染  ==> 得到被替换完的字符串# 2.将字符串封装HttpReponse对象中,等待给用户返回。return render(request, 'login2.html', {"v1": "wupeiqi"})
def render(request, template_name, context=None, content_type=None, status=None, using=None):content = loader.render_to_string(template_name, context, request, using=using)#    template = get_template(template_name, using=using)#    content = template.render(context, request)return HttpResponse(content, content_type, status)
from django.shortcuts import HttpResponse
from django.template.loader import get_templatedef v1(request):template = get_template("v1.html")text = template.render({"text": "张开"}, request)print(text)return HttpResponse("OK")

2.插件相关的类

class Widget(metaclass=MediaDefiningClass):def __init__(self, attrs=None):self.attrs = {} if attrs is None else attrs.copy()def render(self, name, value, attrs=None, renderer=None):# name="user" value="zhangkai"  attrs=None   self.attrs={'class': "c1", "id": "xx1"}context = self.get_context(name, value, attrs)return self._render(self.template_name, context, renderer)def get_context(self, name, value, attrs):return {"widget": {"name": name, # "user""value": self.format_value(value), # "zhangkai""attrs": self.build_attrs(self.attrs, attrs), # {'class': "c1", "id": "xx1"}"template_name": self.template_name, # "django/forms/widgets/text.html"# "type":"text"},}class Input(Widget):input_type = None  # Subclasses must define this.template_name = "django/forms/widgets/input.html"def __init__(self, attrs=None):if attrs is not None:attrs = attrs.copy()self.input_type = attrs.pop("type", self.input_type)super().__init__(attrs)def get_context(self, name, value, attrs):# {"widget":{"name":}   }context = super().get_context(name, value, attrs)context["widget"]["type"] = self.input_typereturn contextclass TextInput(Input):input_type = "text"template_name = "django/forms/widgets/text.html"class PasswordInput(Input):input_type = "password"template_name = "django/forms/widgets/password.html"def __init__(self, attrs=None, render_value=False):super().__init__(attrs)self.render_value = render_valuedef get_context(self, name, value, attrs):if not self.render_value:value = Nonereturn super().get_context(name, value, attrs)
from django.shortcuts import HttpResponse
from django.template.loader import get_templatefrom django import formsdef v1(request):template = get_template("v1.html")text = template.render({"text": "张开"}, request)print(text)return HttpResponse("OK")def v2(request):# 1.执行 TextInput的 __init__方法obj = forms.TextInput(attrs={'class': "c1", "id": "xx1"})data_string = obj.render(name="user", value="张开")print(data_string)  # <input type='text' name='user' value="张开" class="c1"  id="xx1" />obj2 = forms.PasswordInput(attrs={'class': "c2"}, render_value=True)data_string = obj2.render(name="user", value="张开")print(data_string)return HttpResponse("OK")

3.init和new

class Foo(object):def __init__(self,name):self.name = name # 1. __new__ 去创建空对象 {}   -> 构造方法(创建对象)
# 2. __init__在对象中进行初始化 {"name":"武沛齐"}   -> 初始化方法
obj = Foo("武沛齐")
class Foo(object):def __init__(self, name):print("init初始化", self)self.name = namedef __new__(cls, *args, **kwargs):obj = super().__new__(cls)print("new创建对象", obj)return objinstance = Foo("wupeiqi")
print("得到对象", instance)

4.元类

说两句:

  • 默认情况下,类都是由type创建;

    class Info(object):city = "背景"def show(self):print("123")# Info = type("Info", (object,), {"city": "背景", "show": lambda self: print(123)})obj = Info()
    print(obj.city)
    obj.show()
    
  • 想要由其他的东西创建类,就可以使用metaclass进行指定。

    class Info(object,metaclass=其他):city = "背景"def show(self):print("123")
    
    class MyType(type):passclass Info(object, metaclass=MyType):city = "背景"def show(self):print("123")
    

类是有type创建的,类又可以进行实例化,去创建对象。

class MyType(type):# def __init__(self, *args, **kwargs):#     super().__init__(*args, **kwargs)def __new__(cls, *args, **kwargs):clazz = super().__new__(cls, *args, **kwargs)clazz.base_declare = [11, 22, 33]return clazzclass Info(object, metaclass=MyType):city = "背景"def show(self):print("123")print(Info.base_declare)

5.isintance

判断某个对象是否是某个类或其子类创建的对象。

class Foo(object):passclass Info(object):passobj1 = Foo()
obj2 = Foo()print(isinstance(obj1, Foo))
print(isinstance(obj2, Info))
class Field(object):passclass CharField(Field):passclass EmailField(Field):passclass ImageField(Field):passobj1 = CharField()
obj2 = EmailField()
obj3 = ImageField()print(isinstance(obj1, Field))
print(isinstance(obj2, Field))
print(isinstance(obj3, Field))

功能:很多对象可以判断这些对象,都是我Field的子类创建的对象。

2.2 Form组件-定义类

class DeclarativeFieldsMetaclass(MediaDefiningClass):"""Collect Fields declared on the base classes."""def __new__(mcs, name, bases, attrs):# Collect fields from current class and remove them from attrs.attrs["declared_fields"] = {key: attrs.pop(key)for key, value in list(attrs.items())if isinstance(value, Field)}new_class = super().__new__(mcs, name, bases, attrs)# Walk through the MRO.declared_fields = {}for base in reversed(new_class.__mro__):# Collect fields from base class.if hasattr(base, "declared_fields"):declared_fields.update(base.declared_fields)# Field shadowing.for attr, value in base.__dict__.items():if value is None and attr in declared_fields:declared_fields.pop(attr)new_class.base_fields = declared_fieldsnew_class.declared_fields = declared_fieldsreturn new_class
from django import formsclass Form(BaseForm, metaclass=DeclarativeFieldsMetaclass):passclass LoginForm(forms.Form):username = forms.CharField(label="用户名", required=True, widget=forms.TextInput)pwd = forms.CharField(label="密码", required=True, widget=forms.PasswordInput)

LoginForm类其实是由DeclarativeFieldsMetaclass创建的【new】【init】。

2.3 Form组件-创建类的对象

from django import formsclass LoginForm(forms.Form):username = forms.CharField(label="用户名", required=True, widget=forms.TextInput)pwd = forms.CharField(label="密码", required=True, widget=forms.PasswordInput)
form = LoginForm() # __new__   __init__
class BaseForm(RenderableFormMixin):field_order = Nonedef __init__(self,data=None,files=None,auto_id="id_%s",prefix=None,initial=None,....,field_order=None,renderer=None):self.fields = copy.deepcopy(self.base_fields)self.order_fields(  self.field_order if field_order is None else field_order   )self.initial = initial or {}renderer = get_default_renderer()self.renderer = rendererdef order_fields(self, field_order):if field_order is None:returnfields = {}for key in field_order:try:fields[key] = self.fields.pop(key)except KeyError:  # ignore unknown fieldspassfields.update(self.fields)  # add remaining fields in original orderself.fields = fieldsclass Form(BaseForm, metaclass=DeclarativeFieldsMetaclass):passclass LoginForm(forms.Form):username = forms.CharField(label="用户名", required=True, widget=forms.TextInput)pwd = forms.CharField(label="密码", required=True, widget=forms.PasswordInput)form = LoginForm(initial={})

2.4 Form组件-对象.字段

class LoginForm(forms.Form):username = forms.CharField(label="用户名", required=True, widget=forms.TextInput)pwd = forms.CharField(label="密码", required=True, widget=forms.PasswordInput)
def v3(request):form = LoginForm()print(form['username'])  # form.username <input type="text" name="username" required id="id_username">return HttpResponse("OK")
class Foo(object):def __getitem__(self, item):return 999obj = Foo()print(obj)
print(obj['xxxx'])
class BoundField:"A Field plus data"def __init__(self, form, field, name):self.form = form    # Form对象self.field = field  #  forms.CharField(label="用户名", required=True, widget=forms.TextInput)self.name = name    # "username"self.html_name = form.add_prefix(name)self.html_initial_name = form.add_initial_prefix(name)self.html_initial_id = form.add_initial_prefix(self.auto_id)if self.field.label is None:self.label = pretty_name(name)else:self.label = self.field.labelself.help_text = field.help_text or ""def __str__(self):"""Render this field as an HTML widget."""return self.as_widget() # <input type="text" name="username" required id="id_username">def as_widget(self, widget=None, attrs=None, only_initial=False):# 插件对象widget = widget or self.field.widgetif self.field.localize:widget.is_localized = Trueattrs = attrs or {}attrs = self.build_widget_attrs(attrs, widget)if self.auto_id and "id" not in widget.attrs:attrs.setdefault("id", self.html_initial_id if only_initial else self.auto_id)if only_initial and self.html_initial_name in self.form.data:# Propagate the hidden initial value.value = self.form._widget_data_value(self.field.hidden_widget(),self.html_initial_name,)else:value = self.value()# 字符串= 插件forms.TextInput对象.render  《input name='?' class=".."/>return widget.render(name=self.html_initial_name if only_initial else self.html_name,value=value,attrs=attrs,renderer=self.form.renderer,)

2.5 Form组件-可迭代对象

class MyForm(object):def __iter__(self):return iter([11, 22, 33, 44])obj = MyForm()
for item in obj:print(item)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/338340.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android App打包加固后的APK无法安装问题

最近开发的一个应用要上架&#xff0c;正常流程打完包后去加固&#xff0c;由于以前一直用的是360的加固助手&#xff0c;这里开始也是选择用它。 使用360加固&#xff1a; 问题一、开始出现的问题是说应用未签名无法加固&#xff0c;我明明是签名后打的包&#xff0c;怎么会…

Linux日志服务管理

一&#xff1a;日志管理&#xff1a; 1.日志介绍&#xff1a; /var/log/boot.log 系统服务启动的相关信息&#xff0c;文本格式 2.日志的级别&#xff1a; 3.日志的种类及位置&#xff1a; 3.1系统日志&#xff1a; /var/log/secure&#xff1a;系统安全信息 /var/log/messag…

【SpringCloud】之配置中心(进阶使用)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是君易--鑨&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《SpringCloud开发之配置中心》。&#x1f3af;&a…

流程控制语句(关键字break和continue的使用)、质数(素数)判断

目录 一、break和continue的说明 二、质数&#xff08;素数&#xff09;判断 一、break和continue的说明 此外&#xff0c;很多语言都有goto语句&#xff0c;goto语句可以随意将控制转移到程序中的任意一条语句上&#xff0c;然后执行它&#xff0c;但使程序容易出错。Java中的…

在 WinForms 应用程序中实现 FTP 文件操作及模式介绍

在 WinForms 应用程序中实现 FTP 文件操作及模式介绍 简介 在许多应用程序中&#xff0c;能够从远程服务器获取文件是一个非常有用的功能。本文将详细介绍如何在 Windows Forms (WinForms) 应用程序中使用 FTP 协议进行文件操作&#xff0c;包括连接到 FTP 服务器、列出目录、…

小程序商城搭建:快速入门指南

随着移动互联网的普及&#xff0c;小程序商城逐渐成为了商家们进行线上销售的重要渠道。如果你也想搭建一个小程序商城&#xff0c;那么本文将为你介绍如何使用乔拓云这一第三方小程序搭建平台来轻松搭建自己的小程序商城。 一、选择合适的第三方小程序搭建平台 在选择第三方小…

EI级 | Matlab实现VMD-TCN-LSTM变分模态分解结合时间卷积长短期记忆神经网络多变量光伏功率时间序列预测

EI级 | Matlab实现VMD-TCN-LSTM变分模态分解结合时间卷积长短期记忆神经网络多变量光伏功率时间序列预测 目录 EI级 | Matlab实现VMD-TCN-LSTM变分模态分解结合时间卷积长短期记忆神经网络多变量光伏功率时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.【E…

超大规模企业的经验教训:对象存储如何推动下一波托管服务的成功浪潮

在过去的几个月里&#xff0c;我们看到基于对象存储的超快速分析数据库的托管服务有所增加。随着企业意识到将闪电般快速的数据准备与对象存储相结合的战略优势&#xff0c;尤其是对于 AI 和 ML 应用程序&#xff0c;这些托管服务越来越受欢迎&#xff0c;吸引了人们的兴趣和工…

Python从入门到网络爬虫(控制语句详解)

前言 做任何事情都要遵循一定的原则。例如&#xff0c;到图书馆去借书&#xff0c;就需要有借书证&#xff0c;并且借书证不能过期&#xff0c;这两个条件缺一不可。程序设计亦是如此&#xff0c;需要使用流程控制实现与用户的交流&#xff0c;并根据用户需求决定程序“做什么…

2024年工信部AI人工智能证书“计算机视觉工程师”证书报考中!

为进一步贯彻落实中共中央印发《关于深化人才发展体制机制改革的意见》和国务院印发《关于“十四五”数字经济发展规划》等有关工作的部署求&#xff0c;深入实施人才强国战略和创新驱动发展战略&#xff0c;加强全国数字化人才队伍建设&#xff0c;持续推进人工智能专业人员能…

【Copilot使用】

Copilot是什么 copilot有多火&#xff0c;1月4日&#xff0c;科技巨头微软在官网上宣布将为Windows 11 PC推出Copilot键。 Copilot是微软在Windows 11中加入的AI助手&#xff0c;该AI助手是一个集成了在操作系统中的侧边栏工具&#xff0c;可以帮助用户完成各种任务。 Copilo…

【前端】使用javascript开发一个在线RGB颜色转换

欢迎来到《小5讲堂》 大家好&#xff0c;我是全栈小5。 这是是《前端》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深对知识点的理解和掌…