关于django:Django开发0到1开发美多shop项目用户登录模块开发全md文档笔记附代码-文档

本系列文章md笔记(已分享)次要探讨django商城我的项目相干常识。我的项目利用Django框架开发一套前后端不拆散的商城我的项目(4.0版本)含代码和文档。性能包含前后端不拆散,不便SEO。采纳Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(动态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,内部接口:容联云、QQ互联、支付宝。仓库里残缺材料代码:请移步这里获取文档和代码感兴趣的小伙伴能够自取哦,欢送大家点赞转发~共 11 章,132 子模块 账号登录用户名登录1. 用户名登录逻辑剖析 2. 用户名登录接口设计1.申请形式选项计划申请办法POST申请地址/login/2.申请参数:表单参数名类型是否必传阐明usernamestring是用户名passwordstring是明码rememberedstring是是否记住用户3.响应后果:HTML字段阐明登录失败响应谬误提醒登录胜利重定向到首页3. 用户名登录接口定义class LoginView(View): """用户名登录""" def get(self, request): """ 提供登录界面 :param request: 申请对象 :return: 登录界面 """ pass def post(self, request): """ 实现登录逻辑 :param request: 申请对象 :return: 登录后果 """ pass4. 用户名登录后端逻辑class LoginView(View): """用户名登录""" def get(self, request): """ 提供登录界面 :param request: 申请对象 :return: 登录界面 """ return render(request, 'login.html') def post(self, request): """ 实现登录逻辑 :param request: 申请对象 :return: 登录后果 """ # 承受参数 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') # 校验参数 # 判断参数是否齐全 if not all([username, password]): return http.HttpResponseForbidden('短少必传参数') # 判断用户名是否是5-20个字符 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return http.HttpResponseForbidden('请输出正确的用户名或手机号') # 判断明码是否是8-20个数字 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('明码起码8位,最长20位') # 认证登录用户 user = authenticate(username=username, password=password) if user is None: return render(request, 'login.html', {'account_errmsg': '用户名或明码谬误'}) # 实现状态放弃 login(request, user) # 设置状态放弃的周期 if remembered != 'on': # 没有记住用户:浏览器会话完结就过期 request.session.set_expiry(0) else: # 记住用户:None示意两周后过期 request.session.set_expiry(None) # 响应登录后果 return redirect(reverse('contents:index'))5. 常识要点登录的核心思想:认证和状态放弃 ...

February 25, 2024 · 3 min · jiezi

关于django:Django开发0到1开发美多shop项目短信验证码和RabbitMQ全md文档笔记附代码-文档

本系列文章md笔记(已分享)次要探讨django商城我的项目相干常识。我的项目利用Django框架开发一套前后端不拆散的商城我的项目(4.0版本)含代码和文档。性能包含前后端不拆散,不便SEO。采纳Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(动态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,内部接口:容联云、QQ互联、支付宝。仓库里残缺材料代码:https://segmentfault.com/a/1190000044639117感兴趣的小伙伴能够自取哦,欢送大家点赞转发~共 11 章,132 子模块 短信验证码防止频繁发送短信验证码存在的问题:尽管咱们在前端界面做了60秒倒计时性能。然而歹意用户能够绕过前端界面向后端频繁申请短信验证码。解决办法: 在后端也要限度用户申请短信验证码的频率。60秒内只容许一次申请短信验证码。在Redis数据库中缓存一个数值,有效期设置为60秒。1. 防止频繁发送短信验证码逻辑剖析 2. 防止频繁发送短信验证码逻辑实现1.提取、校验send_flagsend_flag = redis_conn.get('send_flag_%s' % mobile)if send_flag: return http.JsonResponse({'code': RETCODE.THROTTLINGERR, 'errmsg': '发送短信过于频繁'})2.从新写入send_flag # 保留短信验证码 redis_conn.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code) # 从新写入send_flag redis_conn.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1)3.界面渲染频繁发送短信提示信息if (response.data.code == '4001') { this.error_image_code_message = response.data.errmsg; this.error_image_code = true;} else { // 4002 this.error_sms_code_message = response.data.errmsg; this.error_sms_code = true;}pipeline操作Redis数据库Redis的 C - S 架构:基于客户端-服务端模型以及申请/响应协定的TCP服务。客户端向服务端发送一个查问申请,并监听Socket返回。通常是以阻塞模式,期待服务端响应。服务端解决命令,并将后果返回给客户端。存在的问题: 如果Redis服务端须要同时解决多个申请,加上网络提早,那么服务端利用率不高,效率升高。解决的方法: 管道pipeline 1. pipeline的介绍管道pipeline能够一次性发送多条命令并在执行完后一次性将后果返回。pipeline通过缩小客户端与Redis的通信次数来实现升高往返延时工夫。实现的原理 实现的原理是队列。Client能够将三个命令放到一个tcp报文一起发送。Server则能够将三条命令的处理结果放到一个tcp报文返回。队列是先进先出,这样就保证数据的程序性。 2. pipeline操作Redis数据库1.实现步骤1. 创立Redis管道2. 将Redis申请增加到队列3. 执行申请2.代码实现 # 创立Redis管道 pl = redis_conn.pipeline() # 将Redis申请增加到队列 pl.setex('sms_%s' % mobile, constants.SMS_CODE_REDIS_EXPIRES, sms_code)pl.setex('send_flag_%s' % mobile, constants.SEND_SMS_CODE_INTERVAL, 1) # 执行申请 pl.execute()异步计划RabbitMQ和Celery生产者消费者设计模式思考:上面两行代码存在什么问题? ...

February 24, 2024 · 3 min · jiezi

关于django:Django开发0到1开发美多shop项目Celery短信和用户注册全md文档笔记附代码已分享

本系列文章md笔记(已分享)次要探讨django商城我的项目开发相干常识。本我的项目利用Django框架开发一套前后端不拆散的商城我的项目(4.0版本)含代码和文档。性能包含前后端不拆散,不便SEO。采纳Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(动态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,内部接口:容联云、QQ互联、支付宝。全套笔记和代码自取移步gitee仓库: gitee仓库获取残缺文档和代码感兴趣的小伙伴能够自取哦,欢送大家点赞转发~共 11 章,63 子模块 用户局部应用Celery实现发送短信在meiduo/meiduo_mall下创立celery_tasks用于保留celery异步工作。 在celery_tasks目录下创立config.py文件,用于保留celery的配置信息 broker_url = "redis://127.0.0.1/14"在celery_tasks目录下创立main.py文件,用于作为celery的启动文件 from celery import Celery # 为celery应用django配置文件进行设置 import osif not os.getenv('DJANGO_SETTINGS_MODULE'): os.environ['DJANGO_SETTINGS_MODULE'] = 'meiduo_mall.settings.dev' # 创立celery利用 app = Celery('meiduo') # 导入celery配置 app.config_from_object('celery_tasks.config') # 主动注册celery工作 app.autodiscover_tasks(['celery_tasks.sms'])在celery_tasks目录下创立sms目录,用于搁置发送短信的异步工作相干代码。 将提供的发送短信的云通信SDK放到celery_tasks/sms/目录下。 在celery_tasks/sms/目录下创立tasks.py文件,用于保留发送短信的异步工作 import loggingfrom celery_tasks.main import appfrom .yuntongxun.sms import CCPlogger = logging.getLogger("django") # 验证码短信模板 SMS_CODE_TEMP_ID = 1@app.task(name='send_sms_code')def send_sms_code(mobile, code, expires): """ 发送短信验证码 :param mobile: 手机号 :param code: 验证码 :param expires: 有效期 :return: None """ try: ccp = CCP() result = ccp.send_template_sms(mobile, [code, expires], SMS_CODE_TEMP_ID) except Exception as e: logger.error("发送验证码短信[异样][ mobile: %s, message: %s ]" % (mobile, e)) else: if result == 0: logger.info("发送验证码短信[失常][ mobile: %s ]" % mobile) else: logger.warning("发送验证码短信[失败][ mobile: %s ]" % mobile)在verifications/views.py中改写SMSCodeView视图,应用celery异步工作发送短信 ...

February 23, 2024 · 4 min · jiezi

关于django:Django开发0到1开发美多shop项目图形和短信验证码全md文档笔记附代码已分享

本系列文章md笔记(已分享)次要探讨django商城我的项目相干常识。我的项目利用Django框架开发一套前后端不拆散的商城我的项目(4.0版本)含代码和文档。性能包含前后端不拆散,不便SEO。采纳Django + Jinja2模板引擎 + Vue.js实现前后端逻辑,Nginx服务器(反向代理)Nginx服务器(动态首页、商品详情页、uwsgi服务器(美多商场业务场景),后端服务:MySQL、Redis、Celery、RabbitMQ、Docker、FastDFS、Elasticsearch、Crontab,内部接口:容联云、QQ互联、支付宝。全套笔记和代码自取移步gitee仓库: gitee仓库获取残缺文档和代码感兴趣的小伙伴能够自取哦,欢送大家点赞转发~共 11 章,132 子模块 图形验证码图形验证码接口设计和定义1. 图形验证码接口设计1.申请形式选项计划申请办法GET申请地址image_codes/(?P[\w-]+)/2.申请参数:门路参数参数名类型是否必传阐明uuidstring是惟一编号3.响应后果:image/jpg 2. 图形验证码接口定义1.图形验证码视图class ImageCodeView(View): """图形验证码""" def get(self, request, uuid): """ :param request: 申请对象 :param uuid: 惟一标识图形验证码所属于的用户 :return: image/jpg """ pass2.总路由 # verifications url(r'^', include('verifications.urls')),3.子路由 # 图形验证码 url(r'^image_codes/(?P<uuid>[\w-]+)/$', views.ImageCodeView.as_view()),图形验证码后端逻辑1. 筹备captcha扩大包提醒:captcha扩大包用于后端生成图形验证码 可能呈现的谬误报错起因:环境中没有Python解决图片的库:PIL 解决办法装置Python解决图片的库:pip install Pillow2. 筹备Redis数据库筹备Redis的2号库存储验证码数据"verify_code": { # 验证码 "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } },3. 图形验证码后端逻辑实现class ImageCodeView(View): """图形验证码""" def get(self, request, uuid): """ :param request: 申请对象 :param uuid: 惟一标识图形验证码所属于的用户 :return: image/jpg """ # 生成图片验证码 text, image = captcha.generate_captcha() # 保留图片验证码 redis_conn = get_redis_connection('verify_code') redis_conn.setex('img_%s' % uuid, constants.IMAGE_CODE_REDIS_EXPIRES, text) # 响应图片验证码 return http.HttpResponse(image, content_type='image/jpg')图形验证码前端逻辑1. Vue实现图形验证码展现1.register.jsmounted(){ // 生成图形验证码 this.generate_image_code();},methods: { // 生成图形验证码 generate_image_code(){ // 生成UUID。generateUUID() : 封装在common.js文件中,须要提前引入 this.uuid = generateUUID(); // 拼接图形验证码申请地址 this.image_code_url = "/image_codes/" + this.uuid + "/"; }, ......}2.register.html<li> <label>图形验证码:</label> <input type="text" name="image_code" id="pic_code" class="msg_input"> <img :src="image_code_url" @click="generate_image_code" alt="图形验证码" class="pic_code"> <span class="error_tip">请填写图形验证码</span></li>3.图形验证码展现和存储成果 ...

February 19, 2024 · 4 min · jiezi

关于django:Django学习笔记012ModelForm和BootStrap

####1、ModelFrom能够主动生成HTML标签1.1 主动生成ID,格局为ID_ models.py create_time = models.DateField(verbose_name='入职工夫')HTMLid="id_create_time"<input type="text" name="create_time" class="form-control" placeholder="入职工夫" required="" id="id_create_time">ModelForm能够帮忙咱们生成HTML标签。 class UserModelForm(forms.ModelForm): class Meta: model = models.UserInfo fields = ["name", "password",]form = UserModelForm(){{form.name}} 一般的input框{{form.password}} 一般的input框定义插件 class UserModelForm(forms.ModelForm): class Meta: model = models.UserInfo fields = ["name", "password",] widgets = { "name": forms.TextInput(attrs={"class": "form-control"}), "password": forms.PasswordInput(attrs={"class": "form-control"}), "age": forms.TextInput(attrs={"class": "form-control"}), }class UserModelForm(forms.ModelForm): name = forms.CharField( min_length=3, label="用户名", widget=forms.TextInput(attrs={"class": "form-control"}) ) class Meta: model = models.UserInfo fields = ["name", "password", "age"]{{form.name}} BootStrap的input框{{form.password}} BootStrap的input框从新定义的init办法,批量设置 class UserModelForm(forms.ModelForm): class Meta: model = models.UserInfo fields = ["name", "password", "age",] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 循环ModelForm中的所有字段,给每个字段的插件设置 for name, field in self.fields.items(): field.widget.attrs = { "class": "form-control", "placeholder": field.label }class UserModelForm(forms.ModelForm): class Meta: model = models.UserInfo fields = ["name", "password", "age",] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 循环ModelForm中的所有字段,给每个字段的插件设置 for name, field in self.fields.items(): # 字段中有属性,保留原来的属性,没有属性,才减少。 if field.widget.attrs: field.widget.attrs["class"] = "form-control" field.widget.attrs["placeholder"] = field.label else: field.widget.attrs = { "class": "form-control", "placeholder": field.label }class UserEditModelForm(forms.ModelForm): class Meta: model = models.UserInfo fields = ["name", "password", "age",] def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # 循环ModelForm中的所有字段,给每个字段的插件设置 for name, field in self.fields.items(): # 字段中有属性,保留原来的属性,没有属性,才减少。 if field.widget.attrs: field.widget.attrs["class"] = "form-control" field.widget.attrs["placeholder"] = field.label else: field.widget.attrs = { "class": "form-control", "placeholder": field.label }自定义类 ...

September 7, 2023 · 2 min · jiezi

关于django:Django学习笔记011搜索与分页

1、组合查问models.PrettyNum.objects.filter(mobile="19999999999",id=12)1.2 传入字典**data_dictdata_dict = {"mboile":"19999999999","id":12}mobile.PrettyNum.objects.filter(**data_dict)2、条件查问models.PrettyNum.objects.filter(id=12) #ID等于12models.PrettyNum.objects.filter(id__gt=12) #ID大于12models.PrettyNum.objects.filter(id_gte=12) #ID大于等于12models.PrettyNum.objects.filter(id_lt=12) #ID小于等于12models.PrettyNum.objects.filter(id_lte=12) #ID小于等于122、字符串查问__startswith 以XXX结尾__endswith 以XXX结尾__contains 蕴含XXX models.PrettyNum.objects.filter(mobile__startswith="19999") #筛选出以19999结尾models.PrettyNum.objects.filter(mobile__endswith="999") #筛选出以999结尾models.PrettyNum.objects.filter(mobile__contains="999") #筛选出蕴含999的3、标记可信代码mark_safe( )mark_safe( )为 (HTML) 输入目标明确地将字符串标记为平安。返回的对象能够在适宜字符串的任何中央应用。form django.utils.safestring import mark_safe for i in range(1,20): ele = '<li><a href="?page={}">{}</a></li>'.format(i,i) page_str_list.append(ele) page_str_list=mark_safe("".join(page_str_list)) 4、查问定义数据条数查问第1-10条数据 queryset = models.PrettyNum.objects.all()[0:10]5、 网址参数读取import copy query_dict = copy.deepcopy(request.GET) query_dict._mutable = True #设置成能够追加 query_dict.setlist("xxx",[123]) #追加网址参数 query_dict.urlencode() #拼接网址

August 30, 2023 · 1 min · jiezi

关于django:Django学习笔记010ModelForm相关

1、获取数据row_object = models.UserInfo.objects.filter(id=nid).first() if request.method == "GET": form = UserModelForm(instance=row_object) return render(request,'user_edit.html',{"form":form})2、更新数据ModelForm实例参数:instance=row_object form=UserModelForm(data=request.POST,instance=row_object) if form.is_valid(): form.save() return redirect("/user/list/") return render(request,'user_edit.html',{"form":form})3、数据排序 order_byASC(正序):models.PrettyNum.objects.all().order_by("level")DESC(倒序):models.PrettyNum.objects.all().order_by("-level") 4、排除字段exclude#全副字段fields = "__all__"#排除某一字段exclude = ['level']5、对用户提交的数据进行格局的校验5.1 正则表达式from django.core.validators import RegexValidatorclass PrettyModelForm(forms.ModelForm): '''新建靓号''' mobile = forms.CharField( label="手机号", validators=[RegexValidator(r'^1[3-9]\d{9}$','手机号格局谬误')] ) class Meta: model = models.PrettyNum # fields = ['mobile','price','level','status'] fields = "__all__"5.2 勾子办法clean_字段名 #验证办法-2:勾子办法from django.core.exceptions import ValidationError def clean_mobile(self): txt_mobile = self.cleaned_data['mobile'] if len(txt_mobile) != 11: #验证不通过 raise ValidationError("格局谬误") #验证通过,返回用户输出的值 return txt_mobile6、重定义ModelFormclass PrettyEditModelForm(forms.ModelForm): '''编辑靓号,定义须要编辑的字段''' mobile = forms.CharField(disabled=True,label="手机号") class Meta: model = models.PrettyNum fields = ['mobile','price','level','status']def pretty_edit(request,nid): '''编辑靓号''' row_object = models.PrettyNum.objects.filter(id=nid).first() if request.method == "GET": form = PrettyEditModelForm(instance=row_object) #如果只容许批改局部字段,须要为编辑性能独自写ModelForm6、查问判断反复字段6.1 查问判断反复字段exists = models.PrettyNum.objects.filter(mobile=XXXX).exists()if exists: raise ValidationError("查问的字段已存在")6.2 排除本身外的其余反复字段self.instance.pk ...

August 26, 2023 · 1 min · jiezi

关于django:Django4Vue3全新技术实战全栈项目-苦哉生长当驿边

download:Django4+Vue3全新技术实战全栈我的项目 Django 4+Vue 3的基本概念Django 4Django 4是一种基于Python语言的高级Web框架,它遵循MVC(模型-视图-控制器)模式,提供了一套残缺的工具和组件,用于疾速开发高效、平安、可扩大的Web利用1。Django 4相比于之前的版本,有以下几个次要的改良3: 反对ASGI(异步服务网关接口),能够让Django利用更好地利用异步编程和WebSockets等技术。反对自动检测并修复零碎时区设置谬误,能够防止时区相干的问题。反对JSONField字段在所有反对的数据库中应用,能够更不便地存储和查问JSON数据。反对在模板中应用点号作为千位分隔符,能够更好看地显示数字。反对在治理界面中自定义主题色彩,能够更个性化地定制外观。Vue 3Vue 3是一种基于JavaScript语言的渐进式前端框架,它通过响应式数据绑定和组件化零碎,让开发者能够轻松地构建交互式和简单的用户界面2。Vue 3相比于之前的版本,有以下几个次要的改良4: 应用Proxy对象重写了响应式零碎,能够进步性能和兼容性,同时反对更多的数据类型和操作。引入了Composition API,能够让开发者更灵便地组织和复用逻辑代码,同时反对TypeScript类型推断。引入了Teleport组件,能够让开发者更不便地将子组件渲染到任意地位,例如模态框或弹出层等。引入了Fragments个性,能够让开发者在模板中返回多个根节点,而不须要额定的包裹元素。引入了多个内置指令和组件,如v-model, v-show, v-if, v-for, Transition, KeepAlive等,能够简化常见的性能实现。Django 4+Vue 3的劣势应用Django 4+Vue 3开发Web利用有以下几个劣势: 能够利用Python和JavaScript两种风行且弱小的编程语言,编写高质量、高效率、高可读性的代码。能够利用Django 4和Vue 3的新个性,如ASGI, JSONField, Composition API, Teleport等,进步利用的性能和用户体验。能够享受Django和Vue生态系统中丰盛的资源和工具,如DRF, GraphQL, Vuex, Axios, Element UI等,疾速搭建和部署利用。Django 4+Vue 3博客平台示例为了展现如何应用Django 4+Vue 3构建一个博客平台,咱们将以「Django 4 + Vue.js 前后端拆散Web开发实战」为参考,简略实现一个前端页面,显示博客列表和博客详情。 首先,咱们须要创立一个Django 4+Vue 3我的项目,能够应用以下命令: 创立一个虚拟环境python -m venv venv 激活虚拟环境source venv/bin/activate 装置Django 4pip install django 创立一个Django我的项目django-admin startproject blog_project 进入我的项目目录cd blog_project 创立一个Django利用python manage.py startapp blog_app 装置Vue CLInpm install -g @vue/cli ...

August 19, 2023 · 1 min · jiezi

关于django:Django-整合-Swagger实现快速-API-文档生成

Django ,作为 Python 编写的一个优良的开源 Web 利用框架,特地实用于疾速开发的团队。对于很多场景来说,咱们须要一份 API 文档,益处切实太多了: 进步开发效率:开发者能够基于 API 文档 疾速学习和尝试 API,同时 Swagger 文件也能够在许多不同的平台上从代码正文中主动生成,缩小了手动编写文档的工夫和精力。不便接口测试:基于 API 文档能够生成客户端 SDK 代码,用于不同平台上的实现,便于开发者进行接口测试。优化团队合作:OpenAPI 有一个弱小的社区,外面有许多强悍的贡献者,能够帮忙团队更好地进行合作开发。不便接口治理:如果可能自动化生成文档,就能够缩小手动编写文档和保护文档的麻烦,每次接口有变动时也能够自动更新文档,便于接口的治理和保护。Swagger 文档介绍Swagger 是一种用于 RESTful API 的开源框架,能够帮忙开发者疾速构建和文档化 API。Swagger 文档提供了一种主动生成和可视化 API 文档的形式,使得 API 的设计和应用更加简略和易懂。Swagger 文档通过形容 API 的门路、参数、申请体、响应和错误码等信息,让开发者能够疾速理解 API 的设计和应用形式,不便开发者进行 API 的集成和调用。 Swagger 2.0 是 Swagger 标准的第二个版本,引入了许多新的性能和改良。与第一个版本相比,Swagger 2.0 增加了对 WebSockets、OAuth2、文件上传和下载等性能的反对,并且进步了形容 API 的精确度和可读性。Swagger 2.0 还提供了一种可扩大的形式,让开发者能够为本人的 API 增加自定义的元数据信息。 OpenAPI 3.0 是 Swagger 的下一代标准,为 RESTful API 提供了一种规范的形容和交互方式。与 Swagger 2.0 相比,OpenAPI 3.0 提供了更严格的模式验证和错误处理,反对更多的数据类型和协定,同时还提供了更好的安全性和可扩展性。OpenAPI 3.0 还提供了更好的分层形容形式,让开发者能够更好地组织和治理 API 的文档。 ...

August 18, 2023 · 2 min · jiezi

关于django:django42-异步ORM的变化持续观察

Django官网有形容 Django异步的变动4.2相比于4.0的变动就是应用sync_to_async最大的变动就是能够应用同步和异步互不影响异步实现models文件夹下的query文件 class BaseIterable: def __init__( self, queryset, chunked_fetch=False, chunk_size=GET_ITERATOR_CHUNK_SIZE ): self.queryset = queryset self.chunked_fetch = chunked_fetch self.chunk_size = chunk_size async def _async_generator(self): # Generators don't actually start running until the first time you call # next() on them, so make the generator object in the async thread and # then repeatedly dispatch to it in a sync thread. sync_generator = self.__iter__() def next_slice(gen): return list(islice(gen, self.chunk_size)) while True: chunk = await sync_to_async(next_slice)(sync_generator) for item in chunk: yield item if len(chunk) < self.chunk_size: break # __aiter__() is a *synchronous* method that has to then return an # *asynchronous* iterator/generator. Thus, nest an async generator inside # it. # This is a generic iterable converter for now, and is going to suffer a # performance penalty on large sets of items due to the cost of crossing # over the sync barrier for each chunk. Custom __aiter__() methods should # be added to each Iterable subclass, but that needs some work in the # Compiler first. def __aiter__(self): return self._async_generator()class ModelIterable(BaseIterable): """Iterable that yields a model instance for each row.""" def __iter__(self): 代码省略class QuerySet(AltersData): """Represent a lazy database lookup for a set of objects.""" def __init__(self, model=None, query=None, using=None, hints=None): self._iterable_class = ModelIterable def __aiter__(self): # Remember, __aiter__ itself is synchronous, it's the thing it returns # that is async! async def generator(): await sync_to_async(self._fetch_all)() for item in self._result_cache: yield item return generator()论断就是__aiter__ 实现了async for 办法,具体的await obj是通过sync_to_async实现感觉ORM层面的异步和同步区别不大,毕竟在数据连贯层面没有变动临时看进去的就这么多,技术无限,后续持续跟进

April 24, 2023 · 2 min · jiezi

关于django:Djangorestframework-使用协程异步-1-视图异步

Django 简介管网有 为什么应用异步因为Djnago在4.0版本之后是反对异步且在4.1里的ORM甚至不须要应用sync_to_async来装璜,rest框架是不反对的协程,在这种状况下应用rest框架会阻塞协程流程.异步根本是web服务开发的趋势,像web框架有fastapi,sanic这些异步框架,Django作为老牌框架像异步迁徙是必然的。为什么要复写rest_framework局部函数因为Django是协程,然而rest不是,会导致调用中途梗塞,python的协程代码一旦有同步代码则全程同步(毕竟每段代码不是子线程)代码generics.pyimport asyncioimport inspectfrom asgiref.sync import sync_to_asyncfrom rest_framework import exceptions, statusfrom rest_framework.generics import GenericAPIView, get_object_or_404from rest_framework.request import Requestfrom rest_framework.views import APIViewfrom tortoise import Modelfrom tortoise.queryset import QuerySetfrom async_drf import mixinsclass AsyncAPIView(APIView): """ 参考: https://github.com/encode/django-rest-framework/issues/7260 Provides async view compatible support for DRF Views and ViewSets. This must be the first inherited class. """ @classmethod def as_view(cls, *args, **initkwargs): """Make Django process the view as an async view.""" view = super().as_view(*args, **initkwargs) async def async_view(*args, **kwargs): # wait for the `dispatch` method return await view(*args, **kwargs) async_view.cls = cls async_view.initkwargs = initkwargs async_view.csrf_exempt = True return async_view async def get_exception_handler_context(self): # 返回异样上下文 return await sync_to_async(super().get_exception_handler_context)() async def get_exception_handler(self): # 不管异样函数是不是协程 return super().get_exception_handler() async def handle_exception(self, exc): """ Handle any exception that occurs, by returning an appropriate response, or re-raising the error. """ if isinstance(exc, (exceptions.NotAuthenticated, exceptions.AuthenticationFailed)): # WWW-Authenticate header for 401 responses, else coerce to 403 auth_header = await sync_to_async(self.get_authenticate_header)(self.request) if auth_header: exc.auth_header = auth_header else: exc.status_code = status.HTTP_403_FORBIDDEN exception_handler = await self.get_exception_handler() context = await self.get_exception_handler_context() # 如果自定义异样函数不是协程 if not asyncio.iscoroutinefunction(exception_handler): response = await sync_to_async(exception_handler)(exc, context) else: response = await exception_handler(exc, context) if response is None: await sync_to_async(self.raise_uncaught_exception)(exc) response.exception = True return response async def initialize_request(self, request, *args, **kwargs): """ Returns the initial request object. """ parser_context = self.get_parser_context(request) return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context, ) async def dispatch(self, request, *args, **kwargs): """Add async support.""" self.args = args self.kwargs = kwargs request = await self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers try: await sync_to_async(self.initial)(request, *args, **kwargs) if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed # accept both async and sync handlers # built-in handlers are sync handlers if not asyncio.iscoroutinefunction(handler): handler = sync_to_async(handler) response = await handler(request, *args, **kwargs) except Exception as exc: response = await self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.responseclass AsyncGenericAPIView(AsyncAPIView, GenericAPIView): async def paginate_queryset(self, queryset): """ Return a single page of results, or `None` if pagination is disabled. """ if self.paginator is None: return None return await self.paginator.paginate_queryset(queryset, self.request, view=self) async def get_queryset(self) -> QuerySet: """ Get the list of items for this view. This must be an iterable, and may be a queryset. Defaults to using `self.queryset`. This method should always be used rather than accessing `self.queryset` directly, as `self.queryset` gets evaluated only once, and those results are cached for all subsequent requests. You may want to override this if you need to provide different querysets depending on the incoming request. (Eg. return a list of items that is specific to the user) """ assert self.queryset is not None, ( "'%s' should either include a `queryset` attribute, " "or override the `get_queryset()` method." % self.__class__.__name__ ) queryset = self.queryset if isinstance(queryset, QuerySet): # Ensure queryset is re-evaluated on each request. queryset = queryset.all() return queryset async def get_object(self) -> Model: """ Returns the object the view is displaying. You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf. """ queryset = await self.filter_queryset(await self.get_queryset()) # Perform the lookup filtering. lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field assert lookup_url_kwarg in self.kwargs, ( "Expected view %s to be called with a URL keyword argument " 'named "%s". Fix your URL conf, or set the `.lookup_field` ' "attribute on the view correctly." % (self.__class__.__name__, lookup_url_kwarg) ) filter_kwargs = {self.lookup_field: self.kwargs[lookup_url_kwarg]} obj = await sync_to_async(get_object_or_404)(queryset, **filter_kwargs) obj = await obj # May raise a permission denied await sync_to_async(self.check_object_permissions)(self.request, obj) return obj async def get_serializer(self, *args, **kwargs): """ Return the serializer instance that should be used for validating and deserializing input, and for serializing output. """ if inspect.iscoroutinefunction(self.get_serializer_class): serializer_class = await self.get_serializer_class() else: serializer_class = await sync_to_async(self.get_serializer_class)() kwargs.setdefault("context", await sync_to_async(self.get_serializer_context)()) return await sync_to_async(serializer_class)(*args, **kwargs) async def get_serializer_class(self): """ Return the class to use for the serializer. Defaults to using `self.serializer_class`. You may want to override this if you need to provide different serializations depending on the incoming request. (Eg. admins get full serialization, others get basic serialization) """ assert self.serializer_class is not None, ( "'%s' should either include a `serializer_class` attribute, " "or override the `get_serializer_class()` method." % self.__class__.__name__ ) return self.serializer_class async def get_paginated_response(self, data): """ Return a paginated style `Response` object for the given output data. """ assert self.paginator is not None return await self.paginator.get_paginated_response(data) async def filter_queryset(self, queryset): """ Given a queryset, filter it with whichever filter backend is in use. You are unlikely to want to override this method, although you may need to call it either from a list view, or from a custom `get_object` method if you want to apply the configured filtering backend to the default queryset. """ for backend in list(self.filter_backends): queryset = await backend().filter_queryset(self.request, queryset, self) if inspect.iscoroutine(queryset): return await queryset return queryset# Concrete view classes that provide method handlers# by composing the mixin classes with the base view.class AsyncCreateAPIView(mixins.AsyncCreateModelMixin, AsyncGenericAPIView): """ Concrete view for creating a model instance. """ async def post(self, request, *args, **kwargs): return await self.create(request, *args, **kwargs)class AsyncListAPIView(mixins.AsyncListModelMixin, AsyncGenericAPIView): """ Concrete view for listing a queryset. """ async def get(self, request, *args, **kwargs): return await self.list(request, *args, **kwargs)class AsyncRetrieveAPIView(mixins.AsyncRetrieveModelMixin, AsyncGenericAPIView): """ Concrete view for retrieving a model instance. """ async def get(self, request, *args, **kwargs): return await self.retrieve(request, *args, **kwargs)class AsyncDestroyAPIView(mixins.AsyncDestroyModelMixin, AsyncGenericAPIView): """ Concrete view for deleting a model instance. """ async def delete(self, request, *args, **kwargs): return await self.destroy(request, *args, **kwargs)class AsyncUpdateAPIView(mixins.AsyncUpdateModelMixin, AsyncGenericAPIView): """ Concrete view for updating a model instance. """ async def put(self, request, *args, **kwargs): return await self.update(request, *args, **kwargs) async def patch(self, request, *args, **kwargs): return await self.partial_update(request, *args, **kwargs)class AsyncListCreateAPIView(mixins.AsyncListModelMixin, mixins.AsyncCreateModelMixin, AsyncGenericAPIView): """ Concrete view for listing a queryset or creating a model instance. """ async def get(self, request, *args, **kwargs): return await self.list(request, *args, **kwargs) async def post(self, request, *args, **kwargs): return await self.create(request, *args, **kwargs)class AsyncRetrieveUpdateAPIView(mixins.AsyncRetrieveModelMixin, mixins.AsyncUpdateModelMixin, AsyncGenericAPIView): """ Concrete view for retrieving, updating a model instance. """ async def get(self, request, *args, **kwargs): return await self.retrieve(request, *args, **kwargs) async def put(self, request, *args, **kwargs): return await self.update(request, *args, **kwargs) async def patch(self, request, *args, **kwargs): return await self.partial_update(request, *args, **kwargs)class AsyncRetrieveDestroyAPIView(mixins.AsyncRetrieveModelMixin, mixins.AsyncDestroyModelMixin, AsyncGenericAPIView): """ Concrete view for retrieving or deleting a model instance. """ async def get(self, request, *args, **kwargs): return await self.retrieve(request, *args, **kwargs) async def delete(self, request, *args, **kwargs): return await self.destroy(request, *args, **kwargs)class AsyncRetrieveUpdateDestroyAPIView( mixins.AsyncRetrieveModelMixin, mixins.AsyncUpdateModelMixin, mixins.AsyncDestroyModelMixin, AsyncGenericAPIView): """ Concrete view for retrieving, updating or deleting a model instance. """ async def get(self, request, *args, **kwargs): return await self.retrieve(request, *args, **kwargs) async def put(self, request, *args, **kwargs): return await self.update(request, *args, **kwargs) async def patch(self, request, *args, **kwargs): return await self.partial_update(request, *args, **kwargs) async def delete(self, request, *args, **kwargs): return await self.destroy(request, *args, **kwargs)mxins.pyfrom typing import Dictfrom asgiref.sync import sync_to_asyncfrom rest_framework import statusfrom rest_framework.mixins import ( CreateModelMixin, DestroyModelMixin, ListModelMixin, RetrieveModelMixin, UpdateModelMixin,)from rest_framework.response import Responsefrom rest_framework.settings import api_settingsclass AsyncCreateModelMixin(CreateModelMixin): """Make `create()` and `perform_create()` overridable. Without inheriting this class, the event loop can't be used in these two methods when override them. This must be inherited before `CreateModelMixin`. class MyViewSet(AsyncMixin, GenericViewSet, AsyncCreateModelMixin, CreateModelMixin): pass """ async def create(self, request, *args, **kwargs): serializer = await self.get_serializer(data=request.data) await sync_to_async(serializer.is_valid)(raise_exception=True) # MODIFIED HERE await self.perform_create(serializer) # MODIFIED HERE headers = await self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) async def perform_create(self, serializer): await sync_to_async(serializer.save)() async def get_success_headers(self, data) -> Dict: try: return {"Location": str(data[api_settings.URL_FIELD_NAME])} except (TypeError, KeyError): return {}class AsyncListModelMixin(ListModelMixin): async def list(self, request, *args, **kwargs): queryset = await self.filter_queryset(await self.get_queryset()) # queryset = await sync_to_async(queryset)() page = await self.paginate_queryset(queryset) if page is not None: serializer = await self.get_serializer(page, many=True) return await self.get_paginated_response(serializer.data) serializer = await self.get_serializer(queryset, many=True) return Response(serializer.data)class AsyncRetrieveModelMixin(RetrieveModelMixin): """ Retrieve a model instance. """ async def retrieve(self, request, *args, **kwargs): instance = await self.get_object() serializer = await self.get_serializer(instance) return Response(serializer.data)class AsyncUpdateModelMixin(UpdateModelMixin): """ Update a model instance. """ async def update(self, request, *args, **kwargs): partial = kwargs.pop("partial", False) instance = await self.get_object() serializer = await self.get_serializer(instance, data=request.data, partial=partial) await sync_to_async(serializer.is_valid)(raise_exception=True) await self.perform_update(serializer) if getattr(instance, "_prefetched_objects_cache", None): # If 'prefetch_related' has been applied to a queryset, we need to # forcibly invalidate the prefetch cache on the instance. instance._prefetched_objects_cache = {} return Response(serializer.data) async def perform_update(self, serializer): await sync_to_async(serializer.save)() async def partial_update(self, request, *args, **kwargs): kwargs["partial"] = True return await self.update(request, *args, **kwargs)class AsyncDestroyModelMixin(DestroyModelMixin): """Make `destroy()` and `perform_destroy()` overridable. Without inheriting this class, the event loop can't be used in these two methods when override them. This must be inherited before `DestroyModelMixin`. class MyViewSet(AsyncMixin, GenericViewSet, AsyncDestroyModelMixin, DestroyModelMixin): pass """ async def destroy(self, request, *args, **kwargs): instance = await self.get_object() # MODIFIED HERE await self.perform_destroy(instance) # MODIFIED HERE return Response(status=status.HTTP_204_NO_CONTENT) async def perform_destroy(self, instance): await sync_to_async(instance.delete)()应用class ProFileUserViewList(AsyncGenericAPIView): queryset = ProfileUser.objects.all() def get_serializer_class(self): if self.request.method == "GET": return ProfileUserListSerializer async def get(self, request): """ 用户列表 :return: """ 结语这只是实现视图异步, 还短少filter,page,swagger等调用异步方才还看一下github的issues 想要rest反对异步还要不少工夫,毕竟django从3.0到4.0也是通过5年借用github issues一句话,Async IO doesn't necessarily speeds up your code, it just reduces the server resources usage for concurrent tasks by leveraging concurrent network IO in a single-threaded application.以上只是集体钻研源码批改实现,我用的数据库是tortoise,但在django4.0上应用也是没有问题

April 24, 2023 · 7 min · jiezi

关于django:Django-信号使用思考

重拾些许对于信号模块应用的记忆,记录对于 Django 信号应用的思考。 本文应用的 Django 的版本是 4.21 源码正文import loggingimport threadingimport weakreffrom django.utils.inspect import func_accepts_kwargslogger = logging.getLogger("django.dispatch")def _make_id(target): """ 对传递进来的函数生成对应的标识,这里应用了 id 函数 """ # 如果对象具备 __func__ 属性,则意味着函数是类中的函数 if hasattr(target, "__func__"): return (id(target.__self__), id(target.__func__)) return id(target)# None 对应的标识,意味着无意义的键NONE_ID = _make_id(None)# A marker for cachingNO_RECEIVERS = object()class Signal: """ Base class for all signals Internal attributes: receivers { receiverkey (id) : weakref(receiver) } """ def __init__(self, use_caching=False): """ 创立一个新的信号对象 Create a new signal. """ # 接收器列表,好比订阅者列表 self.receivers = [] # Django 的 Signal 零碎须要解决多线程环境中的并发问题。在多线程利用中,可能会有 # 多个线程同时操作 Signal 对象,例如连贯或断开接收器、发送信号等。为了确保 Signal # 对象在多线程环境中的一致性和线程平安,Django 应用 threading.Lock 对要害 # 局部的代码进行加锁。 self.lock = threading.Lock() # 是否应用缓存 self.use_caching = use_caching # For convenience we create empty caches even if they are not used. # A note about caching: if use_caching is defined, then for each # distinct sender we cache the receivers that sender has in # 'sender_receivers_cache'. The cache is cleaned when .connect() or # .disconnect() is called and populated on send(). # 缓存发送者对象和对应的接收器 self.sender_receivers_cache = weakref.WeakKeyDictionary() if use_caching else {} # 标识是否存在曾经生效的接收器 self._dead_receivers = False def connect(self, receiver, sender=None, weak=True, dispatch_uid=None): """ 用于将信号接收器(receiver)注册到信号对象(signal)。接收器是一个函数,当信号 被发送时,对应发送者所有对应的接收器将被触发 Connect receiver to sender for signal. Arguments: receiver 接收器 接收器是一个用来接管信号的函数或者对象的办法,接收器必须可 hash。 A function or an instance method which is to receive signals. Receivers must be hashable objects. 当 weak 为 True 时,接收器肯定能够被弱援用。 If weak is True, then receiver must be weak referenceable. 接收器必须能够承受关键字参数 Receivers must be able to accept keyword arguments. 如果一个接收器(A) 连贯时,应用了 dispatch_uid 参数,那么如果其余接收器(B)连贯时, 应用了同样的 dispatch_uid,那么接收器(A)将不会被增加,即 dispatch_uid 不能反复。 If a receiver is connected with a dispatch_uid argument, it will not be added if another receiver was already connected with that dispatch_uid. sender 发送者 一个用于触发接收器响应的对象。如果为 sender 设置一个具体的对象,那么只有来自该 对象发送的信号才会触发接收器。如果省略 sender 参数,那么该接收器将响应所有发送者的信号。 在 django 的调用中,多处基本上都是类。例如 request_started 信号对应的发送者是 class 'django.core.handlers.wsgi.WSGIHandler' The sender to which the receiver should respond. Must either be a Python object, or None to receive events from any sender. weak 弱援用 是否应用对接收器的弱援用。默认状况下,该模块将尝试应用弱援用来援用接收器。 如果这个参数为 false,那么将应用强援用 Whether to use weak references to the receiver. By default, the module will attempt to use weak references to the receiver objects. If this parameter is false, then strong references will be used. dispatch_uid 在可能发送反复信号的状况下,信号接收器的惟一标识符 一个用于惟一地标识一个特定接收器对象的标识符,它通常是一个字符串,尽管它能够是 任何可哈希的货色。 An identifier used to uniquely identify a particular instance of a receiver. This will usually be a string, though it may be anything hashable. """ from django.conf import settings # If DEBUG is on, check that we got a good receiver # 如果开启 DEBUG 模式,检测接收器是否符合要求 if settings.configured and settings.DEBUG: if not callable(receiver): raise TypeError("Signal receivers must be callable.") # Check for **kwargs # 查看接收器接管的是否都是关键字参数 if not func_accepts_kwargs(receiver): raise ValueError( "Signal receivers must accept keyword arguments (**kwargs)." ) # 如果指定了 dispatch_uid,则优先应用 dispatch_uid,所以针对同一个信号,同样的发送者 # dispatch_uid 是不能反复的,否则后续验证 lookup_key 曾经存在的话,接收器则不会退出 # 到接收器列表。 if dispatch_uid: lookup_key = (dispatch_uid, _make_id(sender)) else: lookup_key = (_make_id(receiver), _make_id(sender)) # 默认应用弱援用,这个也是弱援用的妙用之处。 if weak: ref = weakref.ref receiver_object = receiver # Check for bound methods if hasattr(receiver, "__self__") and hasattr(receiver, "__func__"): ref = weakref.WeakMethod receiver_object = receiver.__self__ receiver = ref(receiver) weakref.finalize(receiver_object, self._remove_receiver) with self.lock: # 革除有效的接收器 self._clear_dead_receivers() if not any(r_key == lookup_key for r_key, _ in self.receivers): # 如果接收器对应的键不在信号对象的接收器列表中,则退出到接收器列表中 self.receivers.append((lookup_key, receiver)) # 革除 sender_receivers_cache 缓存 self.sender_receivers_cache.clear() def disconnect(self, receiver=None, sender=None, dispatch_uid=None): """ 为指定的发送者对象移除对应的接收器 Disconnect receiver from sender for signal. 如果应用了弱援用,disconnect 函数不须要调用。因为弱援用的接收器会主动移除。 If weak references are used, disconnect need not be called. The receiver will be removed from dispatch automatically. Arguments: receiver The registered receiver to disconnect. May be none if dispatch_uid is specified. sender The registered sender to disconnect dispatch_uid the unique identifier of the receiver to disconnect """ # 计算索引键 if dispatch_uid: lookup_key = (dispatch_uid, _make_id(sender)) else: lookup_key = (_make_id(receiver), _make_id(sender)) disconnected = False with self.lock: self._clear_dead_receivers() # 通过比照索引键,如果存在,则进行删除 for index in range(len(self.receivers)): (r_key, _) = self.receivers[index] if r_key == lookup_key: disconnected = True del self.receivers[index] break # 删除完后须要重置 sender_receivers_cache 缓存 self.sender_receivers_cache.clear() # 返回是否断开的标识,数据类型为布尔型 return disconnected def has_listeners(self, sender=None): """是否存在指定发送者无效的接收器""" return bool(self._live_receivers(sender)) def send(self, sender, **named): """ 发送信号到指定发送者的接收器中 Send signal from sender to all connected receivers. If any receiver raises an error, the error propagates back through send, terminating the dispatch loop. So it's possible that all receivers won't be called if an error is raised. Arguments: sender The sender of the signal. Either a specific object or None. named Named arguments which will be passed to receivers. Return a list of tuple pairs [(receiver, response), ... ]. """ if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS: return [] return [(receiver, receiver(signal=self, sender=sender, **named)) for receiver in self._live_receivers(sender)] def send_robust(self, sender, **named): """ Send signal from sender to all connected receivers catching errors. Arguments: sender The sender of the signal. Can be any Python object (normally one registered with a connect if you actually want something to occur). named Named arguments which will be passed to receivers. Return a list of tuple pairs [(receiver, response), ... ]. If any receiver raises an error (specifically any subclass of Exception), return the error instance as the result for that receiver. """ if not self.receivers or self.sender_receivers_cache.get(sender) is NO_RECEIVERS: return [] # Call each receiver with whatever arguments it can accept. # Return a list of tuple pairs [(receiver, response), ... ]. responses = [] for receiver in self._live_receivers(sender): try: response = receiver(signal=self, sender=sender, **named) except Exception as err: logger.error( "Error calling %s in Signal.send_robust() (%s)", receiver.__qualname__, err, exc_info=err, ) responses.append((receiver, err)) else: responses.append((receiver, response)) return responses def _clear_dead_receivers(self): """革除有效的接收器""" # Note: caller is assumed to hold self.lock. if self._dead_receivers: self._dead_receivers = False # 迭代解决,获取无效的接收器 # - 如果是强援用,这间接略过 # - 如果是弱援用,弱援用对象执行为 None,则代表是有效的接收器 self.receivers = [ r for r in self.receivers if not (isinstance(r[1], weakref.ReferenceType) and r[1]() is None) ] def _live_receivers(self, sender): """ 依据指定的发送者获取接收器列表 Filter sequence of receivers to get resolved, live receivers. This checks for weak references and resolves them, then returning only live receivers. """ # 初始化接收器列表对象 receivers = None # 如果应用了缓存,同时 _dead_receivers 为 False 时 if self.use_caching and not self._dead_receivers: # 间接通过发送者对象获取接收器列表 receivers = self.sender_receivers_cache.get(sender) # We could end up here with NO_RECEIVERS even if we do check this case in # .send() prior to calling _live_receivers() due to concurrent .send() call. # 如果接收器列表为空,则不做任何动作,间接返回 if receivers is NO_RECEIVERS: return [] # 如果接收器列表为 None if receivers is None: with self.lock: # 革除有效的接收器 self._clear_dead_receivers() senderkey = _make_id(sender) receivers = [] # 依据发送者校验,获取发送者对象对应的接收器列表 for (receiverkey, r_senderkey), receiver in self.receivers: # 因为 sender 在有些信号对象中是为 None,所以须要判断是否是 NONE_ID if r_senderkey == NONE_ID or r_senderkey == senderkey: receivers.append(receiver) # 如果应用治理缓存,则进行缓存 if self.use_caching: if not receivers: self.sender_receivers_cache[sender] = NO_RECEIVERS else: # Note, we must cache the weakref versions. self.sender_receivers_cache[sender] = receivers non_weak_receivers = [] # 迭代解决获取非弱援用的接收器(即失常的接收器) for receiver in receivers: if isinstance(receiver, weakref.ReferenceType): # Dereference the weak reference. receiver = receiver() if receiver is not None: non_weak_receivers.append(receiver) else: # 如果是强援用,则间接退出 non_weak_receivers.append(receiver) return non_weak_receivers def _remove_receiver(self, receiver=None): """ 当弱援用援用的对象不存在时,给以后的信号标识存在有效的接收器 标注 self.receivers 存在有效的弱援用。如果存在有效的弱援用, 将在 connect、disconnect 和 _live_receivers 中清理这些 有效的弱援用对象。 """ # Mark that the self.receivers list has dead weakrefs. If so, we will # clean those up in connect, disconnect and _live_receivers while # holding self.lock. Note that doing the cleanup here isn't a good # idea, _remove_receiver() will be called as side effect of garbage # collection, and so the call can happen while we are already holding # self.lock. self._dead_receivers = Truedef receiver(signal, **kwargs): """ 连贯接收器到信号的装璜器,其外部实际上是对 connect 办法的包装,应用装璜器看起来更直观一些。 A decorator for connecting receivers to signals. Used by passing in the signal (or list of signals) and keyword arguments to connect:: @receiver(post_save, sender=MyModel) def signal_receiver(sender, **kwargs): ... @receiver([post_save, post_delete], sender=MyModel) def signals_receiver(sender, **kwargs): ... """ def _decorator(func): if isinstance(signal, (list, tuple)): for s in signal: s.connect(func, **kwargs) else: signal.connect(func, **kwargs) return func return _decorator2 函数清单2.1 _make_id 办法def _make_id(target): if hasattr(target, "__func__"): return (id(target.__self__), id(target.__func__)) return id(target)首先认真剖析下其业务实现,target 参数是接收器(即一般的函数或者是 bound 办法) ...

April 20, 2023 · 8 min · jiezi

关于django:Requested-setting-INSTALLEDAPPS

Requested setting INSTALLED_APPS, but settings are not configured. File ~/.local/share/virtualenvs/twitter-a7IU1pWC/lib/python3.10/site-packages/django/conf/__init__.py:63, in LazySettings._setup(self, name) 61 if not settings_module: 62 desc = ("setting %s" % name) if name else "settings"---> 63 raise ImproperlyConfigured( 64 "Requested %s, but settings are not configured. " 65 "You must either define the environment variable %s " 66 "or call settings.configure() before accessing settings." 67 % (desc, ENVIRONMENT_VARIABLE)) 69 self._wrapped = Settings(settings_module)ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.应用 python shell 调试 Django 是哒咩的 ...

April 6, 2023 · 1 min · jiezi

关于django:Django笔记二十三之条件表达式搜索更新等操作

这一篇笔记将介绍条件表达式,就是如何在 model 的应用中依据不同的条件筛选数据返回。 这个操作相似于数据库中 if elif else 的逻辑。 以下是本篇笔记的目录: model 和数据筹备When 和 Case 操作新增字段返回条件搜寻条件更新条件聚合1、model 和数据筹备这篇笔记咱们用到的 model 是 Client,放在 blog/models.py 下 以下是 Client 的 model 定义: class Client(models.Model): REGULAR = 'R' GOLD = 'G' PLATINUM = 'P' ACCOUNT_TYPE_CHOICES = [ (REGULAR, 'Regular'), (GOLD, 'Gold'), (PLATINUM, 'Platinum'), ] name = models.CharField(max_length=50) registered_on = models.DateField() account_type = models.CharField( max_length=1, choices=ACCOUNT_TYPE_CHOICES, default=REGULAR, )其中 choices 的操作在后面字段类型中都有介绍到,这里不再赘述。 而后 migrate 相干操作这里不多说了,接下来插入一些数据,在 shell 中执行: from blog.models import ClientClient.objects.create(name="client_1", registered_on="2020-01-01", account_type="R")Client.objects.create(name="client_2", registered_on="2021-07-12", account_type="G")Client.objects.create(name="client_3", registered_on="2022-09-20", account_type="P")Client.objects.create(name="client_4", registered_on="2022-12-07", account_type="P")接下来介绍咱们操作的知识点。 ...

March 13, 2023 · 2 min · jiezi

关于django:Django笔记十八之save函数的继承操作和指定字段更新等实例方法

这篇笔记次要介绍 Django 一些实例办法。 什么是 实例,咱们晓得通过filter() 的一些筛选办法,失去的是 QuerySet,而 QuerySet 取单条数据,通过索引,或者 first() 或者 last() 等办法,失去的单条数据,就是一个 model 的实例。 咱们接下来要介绍的就是这种单条实例的一些办法。 save() 的继承操作refresh from db, 从数据库中更新实例数据自增的主键指定字段更新 save()1、save() 的继承操作对于一个 model,咱们能够通过 save() 的形式创立一条数据,比方: from blog.models import Blogblog = Blog(name="blog_1", tagline="tagline_1")blog.save()对于下面的 blog,咱们就称其为 Blog 的一个实例。 咱们能够通过继承笼罩原有的 save() 办法,而后新增一些咱们须要的操作,比方打印日志,发送揭示等。 办法如下: class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() def save(self, *args, **kwargs): print("save") super(Blog, self).save(*args, **kwargs)这样,咱们在对 Blog 数据进行 save() 操作的时候,就能够看到控制台会输入 "save" 的记录。 除此之外,Django 的文档提出了一种形式,在 model 中定义一个类办法,能够不便咱们对数据进行解决: class Blog(models.Model): name = models.CharField(max_length=100) tagline = models.TextField() @classmethod def create(cls, name, tagline): blog = cls(name=name, tagline=tagline) print("get an unsaved Blog instance") return blog而后通过调用该办法,传入参数,能够失去一个未保留的实例: ...

March 8, 2023 · 2 min · jiezi

关于django:Django笔记八之model中Meta参数的使用

后面介绍了 model 的字段属性,字段类型,这篇笔记介绍一下 model 的 Meta 选项。 这个选项提供了一些参数,比方排序(ordering),表名(db_table)等。 但这都不是必须的,都是作为可选项,次要是为使用者提供方便的、自定义的一些用法。 以下是本次笔记的目录列表: db_tableget_latest_bymanagedordering1、db_table个别如果咱们创立 model 的时候不指定表名,零碎在 makemigration 和 migrate 的时候会默认给咱们增加表名。 规定是:app_name + "_" + model_name 的小写。 比方一个 model 为 TestTableName,放在 blog 这个 application 下,那么在迁徙的时候,数据库表名则是:blog_testtablename。 留神: 上述情况应用的数据库是 oracle,且表名过长,则会因为 oracle 有一个表名长度的限度,会截取表名的长度。 而如果咱们在 Meta 里应用 db_table 参数,则能够间接指定表名,且忽视 application 名称前缀的规定。 以下是应用示例: class TestModel(models.Model): pass class Meta: db_table = 'test_table'那么在执行 migration 的时候,零碎会为这个 model 创立表名为 test_table 的表。 以上也是 Meta 应用的形式。 2、get_latest_by指定 latest() 函数默认应用的字段。 先来介绍一下 latest() 函数,这个函数的应用办法前面会介绍,有一种用法:TestModel.objects.latest('field_name'),这样通过指定字段名称,零碎会返回 TestModel 依照字段名为 field_name 排序的最新的一条数据。 ...

February 27, 2023 · 1 min · jiezi

关于django:Django笔记一之运行系统创建视图并访问

从这一篇笔记开始将依据 Django 的官网文档,浏览整顿之后,出一系列笔记教程,用作新手入门教程或者本人做查阅。 此次 Django 的版本为 3.2,且之后的一系列笔记都将以这个版本为根底,做性能的测试和验证。本篇笔记的目录索引如下: 创立环境运行零碎,在浏览器中拜访介绍 Django 的 application 的根本框架创立视图和接口,在浏览器中拜访接口1、创立环境首先默认咱们曾经配置好了环境,或者可能应用 pycharm 来操作。 应用 conda 创立一个虚拟环境,用的是 py3.6: conda create -n func_test python=3.6进入虚拟环境: source activate func_test装置 Django 的版本为 3.2,通过指定源来减速装置: pip3 install django==3.2 -i https://mirrors.aliyun.com/pypi/simple/而后抉择一个目录,假如是 ~/ 下,创立一个项目名称为 hunter 的我的项目,以下是创立命令: django-admin startproject hunter而后能够看到在 ~/ 下会呈现一个 名为 hunter 的文件夹,这就是咱们刚刚创立好的零碎。 至此,一个 Django 零碎就创立实现了。 2、运行零碎,在浏览器中拜访进入这个文件夹,而后就进入了这个我的项目的根目录,(在此,称进入这个文件夹下第一级目录,为我的项目根目录): cd hunter运行启动命令,以下是启动命令: python3 manage.py runserver 0:9898当咱们在浏览器中拜访 localhost:9898,看到如下页面,即零碎运行胜利:如果是本人服务器或者其余 ip 运行的命令,更改后面的 localhost 即可。 3、介绍 Django 的 application 的根本框架当咱们进入我的项目的根目录,能够看到有一个 manage.py 文件 和一个与咱们项目名称雷同的文件夹。manage.py 文件是咱们运行零碎,以及之后同步数据库构造等操作的一个文件,后续会用到。hunter 文件夹是咱们零碎搁置的一些默认的配置文件等,进入其中,能够看到一个 settings.py 文件和 urls.py 文件,前面咱们会用上。 ...

February 17, 2023 · 1 min · jiezi

关于django:Django之前后端交互

{% load staticfiles %} <link rel="stylesheet" type="text/css" href="{% static 'css/reset.css' %}">#base.html{% block custom_bread %}{% endblock %}#org-list.html{% block custom_bread %}<section> <div class="wp"> <ul class="crumbs"> <li><a href="{% url 'index' %}">首页</a>></li> <li>课程机构</li> </ul> </div></section>{% endblock %}#apps/organizations/views.pyfrom apps.organizations.models import CourseOrgclass OrgView(View): def get(self, request, *args, **kwargs): all_orgs = CourseOrg.objects.all() return render(request, "org-list.html",{ "all_orgs":orgs, })#templates/org-list.html{% for org in all_orgs.object_list %} <dl class="des difdes"> <dt> <a href="{% url 'org:home' org.id %}"> <img width="200" height="120" src="{{ MEDIA_URL }}{{ org.image }}"/> </a> </dt> <dd> <div class="clearfix"> <a href="{% url 'org:home' org.id%}"> <h1>{{org.org_name}}</h1> <div class="pic fl"> {% if org.is_auth %} <img src="{% static 'images/authentication.png' %}"/> {% endif %} {% if org.is_gold %} <img src="{% static 'images/gold.png' %}"/> {% endif %} </div> </a> </div> <ul class="cont"> <li class="first"><p class="pic9">课程数:<span>{{org.course_nums}}</span></p><p class="c7">学习人数:<span>{{org.students}}</span></p></li> <li class="c8" style="padding-left:18px;">{{ org.address }}</li> <li class="pic10" style="padding-left:18px;">经典课程: {% for course in org.courses %} <a href="/diary/19/">{{course.cname}}</a> {% endfor %} <a href="/diary/19/">c语言根底</a> <a href="/diary/16/">数据库根底</a> </li> </ul> </dd> <div class="buy start_groupbuy jsShowPerfect2" data-id="22"><br/>分割<br/>服务</div> </dl> {% endfor %}#apps/organizations/models.pyclass CourseOrg(BaseModel): org_name = models.CharField(max_length=50, verbose_name="机构名称") desc = models.TextField(verbose_name="形容") tag = models.CharField(default="全国出名", max_length=10, verbose_name="机构标签") category = models.CharField(default="pxjg", verbose_name="机构类别", max_length=4, choices=(("pxjg", "培训机构"), ("gr", "集体"), ("gx", "高校"))) click_nums = models.IntegerField(default=0, verbose_name="点击数") fav_nums = models.IntegerField(default=0, verbose_name="珍藏数") image = models.ImageField(upload_to="org/%Y/%m", verbose_name="logo", max_length=100) address = models.CharField(max_length=150, verbose_name="机构地址") students = models.IntegerField(default=0, verbose_name="学习人数") course_nums = models.IntegerField(default=0, verbose_name="课程数") is_auth = models.BooleanField(default=False, verbose_name="是否认证") is_gold = models.BooleanField(default=False, verbose_name="是否金牌") city = models.ForeignKey(City, on_delete=models.CASCADE, verbose_name="所在城市") def courses(self): from apps.course.models import Course courses = Course.objects.filter(course_org=self) return courses class Meta: verbose_name = "课程机构" verbose_name_plural = verbose_name def __str__(self): return self.org_name#apps/course/models.pyfrom apps.organizations.models import CourseOrgclass Course(BaseModel): teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE, verbose_name="讲师") course_org = models.ForeignKey(CourseOrg,related_name='org_name+', null=True, blank=True,max_length=50,on_delete=models.SET_NULL, verbose_name="课程机构") cname = models.CharField(verbose_name="课程名", max_length=50,default="") desc = models.CharField(verbose_name="课程形容", max_length=300) learn_times = models.IntegerField(default=0, verbose_name="学习时长(分钟数)") degree = models.CharField(verbose_name="难度", choices=(("cj", "高级"), ("zj", "中级"), ("gj", "高级")), max_length=2) students = models.IntegerField(default=0, verbose_name='学习人数') fav_nums = models.IntegerField(default=0, verbose_name='珍藏人数') click_nums = models.IntegerField(default=0, verbose_name="点击数") notice = models.CharField(verbose_name="课程布告", max_length=300, default="") category = models.CharField(default="后端开发", max_length=20, verbose_name="课程类别") tag = models.CharField(default="", verbose_name="课程标签", max_length=10) youneed_know = models.CharField(default="", max_length=300, verbose_name="课程须知") teacher_tell = models.CharField(default="", max_length=300, verbose_name="老师通知你") is_classics = models.BooleanField(default=False, verbose_name="是否经典") detail = models.TextField(verbose_name="课程详情") image = models.ImageField(upload_to="courses/%Y/%m", verbose_name="封面图", max_length=100) def courses(self): from apps.course.models import Course courses = Course.objects.filter(course_org=self) return courses class Meta: verbose_name = "课程信息" verbose_name_plural = verbose_name def __str__(self): return self.cname

January 29, 2023 · 2 min · jiezi

关于django:Django大坑之外键设置外键冲突

用Django开发了一个在线教育网站,家喻户晓,Django是一个开发后端的一个弱小框架,用了它就不必管MySQL外面的增删改查,间接在PyCharm里迁徙搞定。想在课程机构页显示课程信息表里的数据,就不得不用到外键。 本文将论述:1、哪一个该做主键表?哪一个该做外键表?它们的区别是什么?2、创立指向同一个模型的多个外键数据迁徙时报错怎么办?3、Django中指向同一模型的外键反向关联产生了抵触怎么办?4、怎么给外键减少related_name属性,自定义关联名称?5、外键删除罕用属性介绍6、数据迁徙中的常见谬误汇总7、编程过程中遇到的一些问题和感悟 接下来,一一解答:1、哪一个该做主键表?哪一个该做外键表?它们的区别是什么?课程信息表蕴含课程机构表里的数据,即课程信息表须要填写是哪个机构,故将机构表和信息表做内连贯,机构表中的主键字段(机构名称)在信息表中做外键,而机构表没有外键,故机构表是主键表,信息表是外键表。区别就是主键表的主键字段在外键表中做外键,而主键表本人却没有外键。鸣谢今春看又过何日是归年的数据库中主键与外键的关系,通俗易懂 2、创立指向同一个模型的多个外键数据迁徙时报错怎么办?解决办法:增加不同的related_name,留神related_name的首个单词肯定不可雷同,否则会报错。鸣谢Aaron_MK的Django的那些坑 3、Django中指向同一模型的外键反向关联产生了抵触怎么办?间接将related_name赋值为加号或以加号结尾的字符串,即可实现禁用反向映射上代码 course_org = models.ForeignKey(CourseOrg,related_name='org_name+', null=True, blank=True,max_length=50,on_delete=models.SET_NULL, verbose_name="课程机构")cname = models.ForeignKey(CourseOrg,related_name='course_name+',null=True, blank=True, max_length=50,on_delete=models.SET_NULL,verbose_name="课程名")鸣谢少女狙击手的python Django 反向拜访器的外键抵触解决 4、怎么给外键减少related_name属性,自定义关联名称?related_name=‘主键字段’鸣谢mmaotai的related_name外表作用 5、外键删除罕用属性介绍CASCADE:这就是默认的选项,级联删除,你无需显性指定它。PROTECT: 保护模式,如果采纳该选项,删除的时候,会抛出ProtectedError谬误。SET_NULL: 置空模式,删除的时候,外键字段被设置为空,前提就是blank=True, null=True,定义该字段的时候,容许为空。SET_DEFAULT: 置默认值,删除的时候,外键字段设置为默认值,所以定义外键的时候留神加上一个默认值。SET(): 自定义一个值,该值当然只能是对应的实体了鸣谢lucky__peng的django中on_delete 6、数据迁徙中的常见谬误汇总6.1ERRORS:auth.User.groups: (fields.E304) Reverse accessor for 'User.groups' clashes with reverse accessor for 'UserProfile.groups'. HINT: Add or change a related_name argument to the definition for 'User.groups' or 'UserProfile.groups'.auth.User.user_permissions: (fields.E304) Reverse accessor for 'User.user_permissions' clashes with reverse accessor for 'UserProfile.user_permissions'. HINT: Add or change a related_name argument to the definition for 'User.user_permissions' or 'UserProfile.user_permissions'.users.UserProfile.groups: (fields.E304) Reverse accessor for 'UserProfile.groups' clashes with reverse accessor for 'User.groups'. ...

January 20, 2023 · 1 min · jiezi

关于django:django-反向解析

在应用Django框架中的反向解析时,查看了django文档、技术博客,现联合Django我的项目来总结反向解析的应用注意事项: 我的项目构造: 全局URL:include()的namespace参数的值能够随便写 利用URL:app_name必须有,并且必须赋值为所在的利用的名字url()函数中name参数的值能够随便写 tmplate.groups.html:在模板中应用namespace:name的模式来应用反向解析,如果要应用变量的值,不须要应用{{变量名}}的模式,间接写变量名即可 参考博客:https://blog.csdn.net/u014745...

January 13, 2023 · 1 min · jiezi

关于django:django基础到高手知识笔记总结50页笔记共10大模块第一期md

django根底到高手常识笔记总结,50页笔记,共10大模块(第一期).md残缺笔记在这: https://zhuanlan.zhihu.com/p/... Django根底到高手残缺笔记 残缺笔记目录: 第一期笔记内容Python Web 框架要点1. Web利用程序处理流程 2. Web程序框架的意义用于搭建Web应用程序免去不同Web利用雷同代码局部的反复编写,只需关怀Web利用外围的业务逻辑实现3. Web应用程序的实质接管并解析HTTP申请,获取具体的申请信息解决本次HTTP申请,即实现本次申请的业务逻辑解决结构并返回处理结果----HTTP响应4. Web框架学习办法如何搭建工程程序 工程的组建工程的配置路由定义视图函数定义如何获取申请数据(操作request对象)如何结构响应数据(结构response对象)框架提供的其余性能组件的应用 数据库模板adminDjango流程重点MVT 流程:把握M,V,T的每个模块的性能,理解MVT的流程 创 建Django我的项目和利用 django-admin startproject namepython manager.py startapp name视 图和ULR 视图的申请和响应URL的匹配门路Django介绍 1. 简介Django, **发音为[`daeŋ]**,是用python语言写的开源web开发框架,并遵循MVC设计。劳伦斯出版团体为了开发以新闻内容为主的网站,而开发进去了这个框架,于2005年7月在BSD许可证下公布。这个名称来源于比利时的爵士音乐家DjangoReinhardt,他是一个吉普赛人,次要以演奏吉它为主,还演奏过小提琴等。**由于Django在近年来的迅速倒退,利用越来越宽泛,被驰名IT开发杂志SDTimes评比为2013SDTimes100,位列"API、库和框架"分类第6位,被认为是该畛域的佼佼者。** Django的 **主要目标是简便、疾速的开发数据库驱动的网站。**它强调代码复用,多个组件能够很不便的以"插件"模式服务于整个框架,Django有许多功能强大的第三方插件,你甚至能够很不便的开发出本人的工具包。这使得Django具备很强的可扩展性。它还强调疾速开发和DRY(DoNotRepeatYourself)准则。 2. 特点1) 重量级框架比照Flask框架,Django原生提供了泛滥的性能组件,让开发更简便疾速。 提供我的项目工程治理的自动化脚本工具数据库ORM反对(对象关系映射,英语:Object Relational Mapping)模板表单Admin治理站点文件治理认证权限session机制缓存2)MVT模式有一种程序设计模式叫 MVC ,其核心思想是 分 工、解耦,让不同的代码块之间升高耦合,加强代码的可扩展性和可移植性,实现向后兼容。 MVC的全拼为 Model-View-Controller,最早由TrygveReenskaug在1978年提出,是施乐帕罗奥多钻研核心(XeroxPARC)在20世纪80年代为程序语言Smalltalk创造的一种软件设计模式,是为了将传统的输出(input)、解决(processing)、输入(output)工作使用到图形化用户交互模型中而设计的。随着规范输入输出设施的呈现,开发人员只须要将精力集中在业务逻辑的剖析与实现上。起初被举荐为Oracle旗下Sun公司JavaEE平台的设计模式,并且受到越来越多的应用ColdFusion和PHP的开发者的欢送。当初尽管不再应用原来的分工形式,然而这种分工的思维被沿用下来,广泛应用于软件工程中,是一种典型并且利用宽泛的软件架构模式。起初,MVC的思维被利用在了Web开发方面,被称为WebMVC框架。MVC模式阐明 M全拼为Model,次要封装对数据库层的拜访,对数据库中的数据进行增、删、改、查操作。V全拼为View,用于封装后果,生成页面展现的html内容。C全拼为Controller,用于接管申请,解决业务逻辑,与Model和View交互,返回后果。Django的MVT M全拼为Model,与MVC中的M性能雷同,负责和数据库交互,进行数据处理。V全拼为View,与MVC中的C性能雷同,接管申请,进行业务解决,返回应答。T全拼为Template,与MVC中的V性能雷同,负责封装结构要返回的html。注 :差别就在于黑线黑箭头标识进去的局部 3. Django学习材料官方网站Github源码Django Book 教程Tange With Django 教程为什么要搭建虚拟环境?在开发过程中, 当须要应用python的某些工具包/框架时须要联网装置 比方联网装置Django框架django的1.11.11版本sudo pip install django提 示:应用如上命令, 会将Django装置到/usr/local/lib/python3.8/dist-packages门路下问 题:如果在一台电脑上, 想开发多个不同的我的项目, 须要用到同一个包的不同版本, 如果应用下面的命令, 在同一个目录下装置或者更新, 新版本会笼罩以前的版本, 其它的我的项目就无奈运行了.解 决计划:虚拟环境 ...

October 19, 2022 · 1 min · jiezi

关于django:django-rest-framework-drf-知识点大集合-共5大模块-第一期

django rest framework drf 知识点大汇合 共5大模块 (第一期) 整个博客系列: Web利用前后端拆散构造Web API接口设计的RESTful格调Django REST framework框架残缺笔记自取:残缺笔记间接在这自取 https://pan.baidu.com/s/1fgLF... 目录: 本期解说正式开始引入Django REST framework在本章中,咱们要大家介绍为什么学习Django REST framework,它能帮忙咱们做哪些事件。 课 程思路: 咱们从剖析当初风行的前后端拆散Web利用模式说起,而后介绍如何设计REST API,通过应用Django来实现一个REST API为例,明确后端开发RESTAPI要做的最外围工作,而后介绍Django REST framework能帮忙咱们简化开发REST API的工作。 Web利用模式在开发Web利用中,有两种利用模式: 前后端不拆散前后端拆散1 前后端不拆散 在前后端不拆散的利用模式中,前端页面看到的成果都是由后端管制,由后端渲染页面或重定向,也就是后端须要管制前端的展现,前端与后端的耦合度很高。 这种利用模式比拟适宜纯网页利用,然而当后端对接App时,App可能并不需要后端返回一个HTML网页,而仅仅是数据自身,所以后端本来返回网页的接口不再实用于前端App利用,为了对接App后端还需再开发一套接口。 2 前后端拆散 在前后端拆散的利用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再管制前端的成果。至于前端用户看到什么成果,从后端申请的数据如何加载到前端中,都由前端本人决定,网页有网页的解决形式,App有App的解决形式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。 在前后端拆散的利用模式中 ,前端与后端的耦合度绝对较低。 在前后端拆散的利用模式中,咱们通常将后端开发的每个视图都称为一个 接 口,或者 API ,前端通过拜访接口来对数据进行增删改查。 ____ 意识RESTful在 前后端拆散的利用模式里,后端API接口如何定义? 例如对于后端数据库中保留了商品的信息,前端可能须要对商品数据进行增删改查,那相应的每个操作后端都须要提供一个API接口: 1. POST /add-goods 减少商品2. POST /delete-goods 删除商品3. POST /update-goods 批改商品4. GET /get-goods 查问商品信息对于接口的申请形式与门路,每个后端开发人员可能都有本人的定义形式,格调迥异。 是否存在一种对立的定义形式,被宽广开发人员承受认可的形式呢? 这就是被广泛采纳的API的RESTful设计格调。 RESTful设计办法1. 域名应该尽量将API部署在专用域名之下。 https://api.example.com如果确定API很简略,不会有进一步扩大,能够思考放在主域名下。 https://example.org/api/2. 版本(Versioning)应该将API的版本号放入URL。 ...

October 17, 2022 · 1 min · jiezi

关于django:DjangoDRF导出excel表格drfrendererxlsx的使用

前言在DRF中,生成excel表格最不便的是借助第三方插件drf-renderer-xlsx,使得“导出”性能变得和写一般视图一样简略、不便、快捷。其思维是基于列表,毕竟list办法生成的queryset曾经和所须要的表格构造相似了,只是须要放在表格文件中。 版本drf-renderer-xlsx==0.4.3Django==3.1.4djangorestframework==3.12.4 配置将以下配置写入 REST_FRAMEWORK REST_FRAMEWORK = { "DEFAULT_RENDERER_CLASSES": [ "rest_framework.renderers.JSONRenderer", "rest_framework.renderers.BrowsableAPIRenderer", "drf_renderer_xlsx.renderers.XLSXRenderer", ],}视图首先看一个简略的导出视图实现 from drf-renderer-xlsx import XLSXFileMixinfrom drf-renderer-xlsx import XLSXRendererfrom rest_framework import viewsets, filters, mixinsclass ExportViewSet(mixins.ListModelMixin, GenericViewSet, XLSXFileMixin): renderer_classes = (XLSXRenderer,) queryset = Model.objects.all() serializer_class = ExportSerializer xlsx_use_labels = True导出视图就和一般的list视图相似,同时继承ListModelMixin,GenericViewSet,以及咱们的配角XLSXFileMixinrenderer_classes 指定渲染器,必须要queryset 汇合serializer_class 序列化器xlsx_use_labels 默认为False,可要可不要,此属性的作用是设置表头的名称。默认是字段名,为True时,在serializer中联合属性label能够指定表头名称为label值,例如class ExportSerializer(serializers.Serializer): name = serializers.SerializerMethodField(label="姓名")默认表头名称为“name”,为True时,名称为"姓名" 再配置url,向url申请就能够取得一个excel表格。简略的配置就到这里。 小结要实现导出表格性能,须要: 写入配置项在list视图的根底上,继承XLSXFileMixin,设置渲染器renderer、汇合queryset、序列化器要想指定表头的名称,增加xlsx_use_labels=True,同时在序列化器中申明字段的label值。默认为模型的字段名。一些其余属性及性能在开发导出性能的时候,咱们常常会遇到一些其余的性能需要,以下都是在视图类中的设置。 设置导出的文件名称 filename = "my_export.xlsx" # 设置属性 filename默认为 export.xlsx还能够通过编写办法去笼罩来设置文件名,办法名:get_filename() 疏忽字段 xlsx_ignore_headers = [<fieldname>] # 疏忽的字段此属性是设置在视图类下的,疏忽字段也能够在序列化器中实现。(序列化器如果继承的是Serializer不申明就能够,如果是ModelSerializer能够应用,也能够通过重写序列化器中的to_representation()办法。) 命名布尔值 xlsx_boolean_labels = {True: _('Yes'), False: _('No')}将布尔值中的True替换为Yes,False替换为No,也可在serilaizer中解决。 ...

October 10, 2022 · 1 min · jiezi

关于django:全栈实现微电商平台

开发环境前置Linuxpython3.5后端环境搭建装置pipenv和依赖包 # 创立我的项目目录mkdir emall && cd emall# pipenv$ pip3 install --user pipenv$ pipenv --version# 依赖包pipenv install Django==2.1.5 djangorestframework==3.9.1创立django我的项目 # 启动虚拟环境$ cd emall && pipenv shell# 创立我的项目emall$ django-admin startproject emall .# 查看目录构造$ lsdb.sqlite3 emall manage.py Pipfile Pipfile.lock$ tree emall [15:11:33]emall|-- __init__.py|-- settings.py|-- urls.py|__ wsgi.py0 directories, 4 files# 启动我的项目$ python manage.py runserver配置数据库 # 创立数据库 emall,编码应用 utf8mb4$ mysql -uroot -e "CREATE DATABASE emall CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"# 编辑 emall/settings.py,找到 DATABASES 的配置$ vi emall/settings.py...DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'emall', 'USER': 'root', 'PASSWORD': '', 'HOST': 'localhost', 'PORT': '3306', }}...# 应用 mysqlclient 连贯 MySQL 数据库$ pipenv install mysqlclient$ pipenv shell && python manage.py migrate# 查看数据库emall$ mysql -uroot -e "show tables in emall;"治理站点(admin) ...

October 10, 2022 · 1 min · jiezi

关于django:基于Django的医案校对网站设计与实现2

1 后盾治理批改--减少栏目在左侧减少自定义的栏目是网站我的项目的常见需要。因为Django后盾栏目是依据Model主动生成的,所以能够在model.py中定义一个model,而后在admin.py中定义对应的类,并注册下来,这样就会在左侧主动生成一个栏目。model.py中增加如下类: class CheckAll(models.Model): class Meta: app_label = 'case_check' verbose_name = '校对批量调配(按起源)' verbose_name_plural = '校对批量调配(按起源)'在admin.py中增加如下的类(此类的性能还没有实现,前期再实现): @admin.register(CheckAll)class CheckAllAdmin(admin.ModelAdmin): def changelist_view(self, request, extra_content=None): return request这样,左侧就有了“校对批量调配(按起源)”的栏目。 2 后盾治理批改--change_list页面批改需要:须要在admin后盾的list页面上减少链接(或者是按钮)“显示已校对”、“显示未校对”、“显示所有”,点击之后list页面依照对应要求显示内容。 2.1 用action的办法实现--失败因为对admin后盾不相熟,开始在action外面增加一个动作,想通过action实现此性能。后果发现,在点击go之后,尽管会去执行action对应的函数外面的代码,然而还是返回到以后的model list页面执行所有记录的查问。所以此路不通。增加action办法,在admin.py文件对应的XXModelAdmin类中增加如下代码: # 批改action内容 actions = ['show_all'] def show_all(self, request, queryset): pass show_all.short_description = "显示已校对" show_all.acts_on_all = Trueaction还有一个问题,就是在执行go操作之前必须抉择至多一条记录进行操作,去掉此限度,能够在changelist_view()中退出如下代码实现: # 移除action必须抉择一个记录的限度 def changelist_view(self, request, extra_context=None): try: action = self.get_actions(request)[request.POST['action']][0] action_acts_on_all = action.acts_on_all except (KeyError, AttributeError): action_acts_on_all = False if action_acts_on_all: post = request.POST.copy() post.setlist(admin.helpers.ACTION_CHECKBOX_NAME, self.model.objects.values_list('id', flat=True)) request.POST = post return super(OriginCaseAdmin, self).changelist_view(request, extra_context)2.2 在change_list页面上增加链接为了可能在后盾列表页面上进行批改,必须批改对应的模板文件,admin后盾的模板文件没有放在我的项目外面,而是放在Django的源码中,其体门路是在你我的项目的虚构门路下:venv4network\Lib\site-packages\django\contrib\admin\templates\adminDjango的admin后盾列表页面对应的是change_list.html页面,须要将此文件复制到模板文件夹下。在我的项目的templates目录下,新建admin文件夹,在新建项目名称的文件夹(我这里是case_check),在新建你对应的Model类名称的文件夹(我这里是origincase),而后把change_list.html文件复制在此文件夹中。关上change_list.html,在对应地位增加一个div,把咱们对应的链接增加下来,上面截取局部代码: ...

September 30, 2022 · 2 min · jiezi

关于django:基于Django的医案校对网站设计与实现

因为钻研须要对已采集的医案进行结构化解决并进行校对,故开发此网站,上面简略记录思路和一些步骤,免得前期遗记。 1 需要剖析设计有三个表,在设计的word文档上。 2 构建Django我的项目关上Pycharm,创立一个Django我的项目,如下图。 3 创立App在我的项目下创立一个case_check的app,用命令创立。首先进入我的项目目录并启动虚拟目录,如图所示。而后,用上面命令创立app:python manage.py startapp case_check失去下图红色区域所示构造的app。 4 编写models上面是原始医案的model class OriginCase(models.Model): content = models.TextField(verbose_name="医案内容") prescription = models.CharField(max_length=255, verbose_name="处方(方剂名称)") herbs = models.TextField(verbose_name="处方对应的中药汇合") syndrome = models.CharField(max_length=50, verbose_name="诊断的证型") symptoms = models.CharField(max_length=1024, verbose_name="症状汇合") symptom_elements = models.CharField(max_length=1024, verbose_name="证素汇合") source = models.CharField(max_length=100, verbose_name="来源于哪一本书或网站") doctor = models.CharField(max_length=100, verbose_name="开处方的医生名字") date = models.DateTimeField(auto_now_add=True, verbose_name="医案录入工夫") check_flag = models.CharField(max_length=10, verbose_name="是否曾经安顿校对,也就是此医案是否曾经进入到checcase表中")5 数据迁徙5.1 创立迁徙文件完了之后,须要创立迁徙文件(migration)。在命令行执行命令(要留神:case_check是刚刚创立的app,须要把这个带上,不然会提醒:No changes detected): python manage.py makemigrations case_check这时候报错:No installed app with label 'case_check'.剖析起因是app没有在settings.py文件中配置下来。关上settings.py文件,在INSTALLED_APPS列表中退出刚刚创立的case_check这个app,如下图红色框中局部:再次在命令行中执行python manage.py makemigrations case_check,如下提醒示意迁徙文件创建胜利: (venv4network) D:\mypython\TCMWeb>python manage.py makemigrations case_checkMigrations for 'case_check': case_check\migrations\0001_initial.py - Create model OriginCase5.2 执行数据迁徙后面步骤中创立好数据迁徙文件之后,开始执行数据迁徙,数据迁徙实现之后,就会在数据库中创立对应的表。首先,须要在setting.py中配置数据库连贯信息,默认状况下Django用的是SQLlite,本我的项目用的MySQL,所以须要重新配置。配置代码如下: ...

September 19, 2022 · 1 min · jiezi

关于django:django-rest-framework-知识笔记点大集合-共5大模块全网最全知识体系

笔记介绍Web利用前后端拆散构造Web API接口设计的RESTful格调Django REST framework框架笔记获取的地址为: https://zhuanlan.zhihu.com/p/... 笔记目录: 意识RESTful在前后端拆散的利用模式里,后端API接口如何定义? 例如对于后端数据库中保留了商品的信息,前端可能须要对商品数据进行增删改查,那相应的每个操作后端都须要提供一个API接口: POST /add-goods 减少商品POST /delete-goods 删除商品POST /update-goods 批改商品GET /get-goods 查问商品信息对于接口的申请形式与门路,每个后端开发人员可能都有本人的定义形式,格调迥异。 是否存在一种对立的定义形式,被宽广开发人员承受认可的形式呢? 这就是被广泛采纳的API的RESTful设计格调。 RESTful设计办法1. 域名应该尽量将API部署在专用域名之下。 https://api.example.com如果确定API很简略,不会有进一步扩大,能够思考放在主域名下。 https://example.org/api/2. 版本(Versioning)应该将API的版本号放入URL。 http://www.example.com/api/1.0/foohttp://www.example.com/api/1.1/foohttp://www.example.com/ap、/2.0/foo另一种做法是,将版本号放在HTTP头信息中,但不如放入URL不便和直观。Github采纳这种做法。 因为不同的版本,能够了解成同一种资源的不同表现形式,所以应该采纳同一个URL。版本号能够在HTTP申请头信息的Accept字段中进行辨别(参见Versioning REST Services): Accept: vnd.example-com.foo+json; version=1.0Accept: vnd.example-com.foo+json; version=1.1Accept: vnd.example-com.foo+json; version=2.01. 装置DRFpip install djangorestframework2. 增加rest_framework利用咱们利用在Django框架学习中创立的demo工程,在settings.py的INSTALLED_APPS中增加'rest_framework'。 INSTALLED_APPS = [ ... 'rest_framework',]接下来就能够应用DRF进行开发了。

September 16, 2022 · 1 min · jiezi

关于django:Django-Swagger文档库drfspectacular

在应用DRF的时候,通常的文档有:默认文档RestFrameWork、CoreAPI、Swagger,Swagger是最风行的API文档库,在绝大多数服务端开发中都有用到,之前咱们应用了CoreAPI来生成文档,一方面是它不够风行,没方法和其余工具联合,另一方面可能是我不相熟,所有有些接口并不能依照咱们的要求来应用。因而我抉择应用Swagger文档,之前应用过drf-yasg,然而drf-yasg当初还不反对OpenAPI 3.0,而在drf-yasg的官网文档中为咱们举荐了另一个库:drf-spectacular,而且申明了drf-yasg不太可能反对OpenAPI 3.0,因而举荐咱们应用drf-spectacular这个库。 装置配置pipenv install drf-spectacular在app中注册 # settings.pyINSTALLED_APPS = [ # ALL YOUR APPS 'drf_spectacular',]配置DRF默认schema # settings.pyREST_FRAMEWORK = { # YOUR SETTINGS 'DEFAULT_SCHEMA_CLASS': 'drf_spectacular.openapi.AutoSchema',}配置drf-spectacular # settings.pySPECTACULAR_SETTINGS = { 'TITLE': '在线考试', 'DESCRIPTION': '在线考试零碎', 'VERSION': '1.0.0', 'SERVE_INCLUDE_SCHEMA': False, # OTHER SETTINGS}动态资源引入drf-spectacular 默认不蕴含UI资源,采纳CDN形式引入网络内部资源,如果须要本地应用UI资源,能够依照一下形式引入: pipenv install drf-spectacular[sidecar]配置settings.py文件 INSTALLED_APPS = [ # ALL YOUR APPS 'drf_spectacular', 'drf_spectacular_sidecar', # required for Django collectstatic discovery]SPECTACULAR_SETTINGS = { 'SWAGGER_UI_DIST': 'SIDECAR', # shorthand to use the sidecar instead 'SWAGGER_UI_FAVICON_HREF': 'SIDECAR', 'REDOC_DIST': 'SIDECAR', # OTHER SETTINGS}路由配置在根urls.py中减少路由配置 ...

September 9, 2022 · 2 min · jiezi

关于django:Django-ForeignKey关联查询

明天用到ForeignKey遗记怎么用了,网上查了一大堆写的乌七八糟,最初终于登录了django官网看了以下文档,真是写的简单明了,搞不懂网上一些教程非要将简略的货色复杂化。 依据官网的解释,我再来简化以下 第一步创立模型: # 一级分类表class TopCategory(BaseModel): title_zh = models.CharField(max_length=32, verbose_name='中文题目')# 二级分类class CategoryTag(BaseModel): title_zh = models.CharField(max_length=32, verbose_name='中文题目') top_category = models.ForeignKey(to=TopCategory, on_delete=models.DO_NOTHING, related_name='topcategory', verbose_name='关联外键')反向查问 就是用被关联的模型(一级分类)查问关联的模型(二级分类) #获取本身id为1的数据,例如一级分类下的:动物row_data = models.TopCategory.objects.get(id=1)#而后查看一级分类下有哪些二级分类,动物->乌龟,兔子,小鸟,麻雀...res = row_data.topcategory.all()正向查问 和下面反过来 #获取获取所有二级分类数据row_data = models.CategoryTag.objects.all()#而后查问这些二级分类都对应者那些一级分类例如[水,华,冰块,石头]->天然,[老虎,狮子]->动物res = row_data.top_category #间接获取一级分类名称,如果须要获取ID学写top_category_id

August 21, 2022 · 1 min · jiezi

关于django:Django后端设置了跨域前端vue怎么还提示跨域错误

后端应用 django-cors-headers INSTALLED_APPS = [ # 配置跨域 'corsheaders', 'home',]MIDDLEWARE = [ # 配置中间件 响应头跨域 'corsheaders.middleware.CorsMiddleware',]# 设置跨域白名单CORS_ORIGIN_WHITELTST = ( 'http://www.00000.com:8081')# 是否容许ajax跨域申请携带cookieCORS_ALLOW_CREDENTIALS = False前端vue拜访https://www.00000.com:8081/ho...接口还是报错,前端跨域谬误,以上接口是本地测试接口。

August 13, 2022 · 1 min · jiezi

关于django:Django解决跨域

Django应用第三方模块解决跨域 装置模块: pip install django-cors-headers在我的项目的settings.py配置应用 一:注册模块, 在INSTALLED_APPS中注册 INSTALLED_APPS = [ # 配置跨域 'corsheaders',]二:注册中间件,模块次要设置一个跨域申请头 MIDDLEWARE = [ # 配置中间件 响应头跨域 'corsheaders.middleware.CorsMiddleware',]三:配置白名单,并且容许ajax跨域不携带cookie拜访 # 设置跨域白名单CORS_ORIGIN_WHITELTST = ( 'http://www.lyweb.com:800')# 是否容许ajax跨域申请携带cookie False示意不须要CORS_ALLOW_CREDENTIALS = False

August 9, 2022 · 1 min · jiezi

关于django:django之MVT模式介绍

本文教程操作环境:windows7零碎、django2.1,DELL G3电脑。 1、MVT模式 django 框架是 MVT 构造, M(model),V(view),T(templates)。 M 代表模型(Model),即数据存取层。 该层解决与数据相干的所有事务: 如何存取、如何验证有效性、蕴含哪些行为以及数据之间的关系等。 T 代表模板(Template),即体现层。 该层解决与体现相干的决定: 如何在页面或其余类型文档中进行显示。 V 代表视图(View),即业务逻辑层。 该层蕴含存取模型及调取失当模板的相干逻辑。 你能够把它看作模型与模板之间的桥梁。 2、具体开发的模块 url(发送什么申请)也就是你在浏览器中要拜访的 url 链接,view(后盾逻辑),网站页面业务逻辑,template(html5页面)你要给用户展现的内容,model(数据库)用来寄存网站所需的数据信息。 开发一个比较简单的网站,说白了就是对数据库增删改查操作,应用 django 框架时,你只有在 settings.py(框架的一些根本配置,比方数据库连贯,地区工夫,admin语言设置等等) urls.py (url 网络链接地址) views.py (网站页面业务逻辑,要实现的性能) templates (网页展现内容) models.py (网站所需数据的存储,这个是web开发最重要的局部)等这些文件或者文件夹编写代码,进行折腾就行。 以上就是django之MVT模式介绍,置信大家曾经对django这部分的内容有所理解,想要进一步的有所应用,还要就这些要点进行深刻学习。

July 11, 2022 · 1 min · jiezi

关于django:如何创建Django目录结构

对于一个我的项目来说,如果可能把握其目录构造,就能对整体的我的项目有一个初步的理解。在咱们创立好一个我的项目后,能够对其中创立的目录构造进行查阅,很多小伙伴们对于目录中的文件还是比拟含糊的。上面咱们先为大家简略介绍创立目录的办法,而后一起找寻创立后的目录构造。 1、先创立Django我的项目,只须要在装置了Django之后,在命令行中输出: django-admin startproject 项目名称例 :创立我的项目BookManagerdjango-admin startproject BookManager就可能实现咱们的一个我的项目创立。 2、如果应用的是pycharm编辑器,也能够间接创立Django我的项目 根本我的项目创立结束,咱们来看看创立实现后工程目录外面到底有些什么文件: BookManager : 是与我的项目同名的文件, 外部蕴含如下我的项目的配置文件。 init.py : 是示意文件BookManager能够被当作包应用。 settings.py : 是我的项目的整体配置文件。 urls.py : 是我的项目的URL配置文件。 wsgi.py : 是我的项目与WSGI兼容的Web服务器入口。 manage.py : 是我的项目运行的入口, 指定配置文件门路。 以上就是创立Django的目录构造,置信通过本篇的学习,大家曾经对我的项目的创立有所理解并找到了无关目录中的一些文件。大家在看完后,能够依据下面的步骤逐渐执行。

July 11, 2022 · 1 min · jiezi

关于django:Django中如何建立mvc模式

在之前的java里,咱们会频繁的提到mvc模式,置信大家曾经对这种模式有了初步的意识。同样的,在Django框架里也有着这类模式的应用,尽管在应用的细节上有所差异,不过其根本的原理还是不会变动太大的。上面咱们就Django中建设mvc模式的办法带来介绍,一起看看怎么用吧。 1、阐明 (1)models.py 文件次要用一个 Python 类来描绘数据表。 称为模型(model) 。使用这个类(通过Django自带的ORM实现),你可能通过简略的 Python 的代码来创建、检索、更新、删除 数据库中的记录。 (2)views.py文件蕴含了页面的业务逻辑,latest_books()函数叫做视图。 (3)urls.py指出了什么样的URL调用什么的视图。在这个例子中,/latest/URL将会调用latest_books()这个函数。换句话说,假设你的域名是example.com,任何人浏览http://example.com/latest/将会调用latest_books()这个函数。 (4)latest_books.html 是 html 模板,它描绘了这个页面的设计是如何的。 使用带基本逻辑申明的模板语言,如{% for book in book_list %}。 2、实例 上面是一个简略的例子介绍Django中的MVC(模型-视图-控制器)设计形式: # models.py (the database tables) from django.db import models class Book(models.Model): name = models.CharField(max_length=50) pub_date = models.DateField() # views.py (the business logic) from django.shortcuts import render_to_responsefrom models import Book def latest_books(request): book_list = Book.objects.order_by('-pub_date')[:10] return render_to_response('latest_books.html', {'book_list': book_list}) # urls.py (the URL configuration) from django.conf.urls.defaults import *import views urlpatterns = patterns('', (r'^latest/$', views.latest_books),) # latest_books.html (the template) <html><head><title>Books</title></head><body><h1>Books</h1><ul>{% for book in book_list %}<li>{{ book.name }}</li>{% endfor %}</ul></body></html>以上就是Django中建设mvc模式的办法,对于mvc模式还不太熟悉的,能够对这种模式做一个理解,而后在Django中对mvc模式的无关应用开展练习。 ...

July 11, 2022 · 1 min · jiezi

关于django:django使用crontab定时

当进行django开发时,通常会做一些非凡的定时工作,如定时执行工作、查看订单等。它能够是一个时间段,例如每10分钟执行一次,也能够是一个固定的工夫。咱们能够通过django中应用crontab库来进行解决,当然在之前咱们要对其进行装置,而后再开展具体的定时办法解说。 1、装置 pip install django-crontab 2、增加配置到 settings.py INSTALLED_APPS 中 INSTALLED_APPS = ( 'django_crontab', ...)3、编写定时函数: 定时工作能够分成两种,一种是执行自定义的mange.py的命令,另一种是执行自定义函数。 在django的app中新建一个myapp/cron.py文件,把须要定时执行的代码放进去 示例: def my_scheduled_job(): Pass4、在 settings.py 中减少CRONJOBS配置 CRONJOBS = [ ('*/5 * * * *', 'myapp.cron.my_scheduled_job')]5、增加并启动定时工作 #增加并启动定时工作python manage.py crontab add以上就是django应用crontab定时的办法,django定时工作django-crontab库的教程和材料比拟多,尽管star数只有500,但API接口比较简单,拜访也很不便,性能也很全面,当然,也有这个不能解决的问题,应用时要留神。

July 11, 2022 · 1 min · jiezi

关于django:WallysQCA9882Access-Point-Wireless-Module-Wireless-AC

QCA9882/Access Point Wireless Module Wireless AC/AN MiniPCIE Standard Card 802.11AC 802.11AN wifi QCA9882 2x 2 5G High power Radio card **DR882** https://www.wallystech.com/Ne... MT7915/MT 7975/IPQ6000/IPQ6018/IPQ6010/IPQ4019/IPQ4029/ipq4018/IPQ8072/IPQ8074/QCN9074/QCN9072/QCN9024/IPQ5018/BY:Wallys Communications (Suzhou ) Co., LTDEMAIL:sales3@wallystech.com Wallys Communications (SuZhou) Co., Ltd., http://www.wallystech.com,which is a professional supplier specializing in product design, manufacturing and offering superior OEM/ODM/JDM services in wireless communications. As a specialized manufacturer and exporter for these products in China,We sincerely hope to establish business relations with your esteemed corporation. We mainly develop high power wireless products based on Quacomm chip such asIPQ6000/IPQ6018/IPQ6010/IPQ4019/IPQ4029/IPQ8072/IPQ8074/QCN9074 and so on . Product Description 882-NAS based on QCA9882 chipset is an enterprise wireless module integrated with 2×2 5G high power Radio card designed specifically to provide users with mobile access to high-bandwidth video streaming, voice, and data transmission for office and challenging RF environment in factories, warehouses establishment. ...

June 29, 2022 · 1 min · jiezi

关于django:经验分享Django开发中常用到的数据库操作总结

查问类操作1)查问所有的后果,相当 sql 中的 select * fromlist = Test.objects.all() 2)条件查问,filter 相干 sql 中的 where,用于过滤查问后果传多个参数:result = Test.objects.filter(id=1, name=’test’) 如果多条件与查问,间接用逗号隔开,filter函数外面的参数都是Test Model中的字段 3)获取单个对象,get 办法的参数个别为 Model 的主键,如果找不到会报错test_obj = Test.objects.get(id=1) 4)限度返回的后果数据的数量,相当于 sql 中的 limit,其中 order_by 是用于排序,如果依据字段 a 倒序排序,就是 order_by(“-time”)Test.objects.order_by('name')[0:2] 5)链式查问Test.objects.filter(name=’test’).order_by(“-ctime”) 6)多条件参数查问,传字典,结构查问条件data = Test.objects.filter(**query_dict).order_by(“-ctime”).values其中query_dict为一个字典,key为条件字段,value为条件值query_dict = {'id':123,'name':’yyp’} 7)传 Q 对象,结构查问条件 在 filter() 等函式中关键字参数彼此之间都是 “and” 关系。然而要执行更简单的查问(比方,实现筛选条件的 or 关系),能够应用 Q 对象。Q对象包含 AND 关系和 OR 关系Q 对象能够用&和 | 运算符进行连贯。当某个操作连贯两个 Q 对象时,就会产生一个新的等价的 Q 对象1、第一步,结构Q对象:fromdjango.db.models import QQ(name__startswith=’h’) | Q(name__startswith=’p’) 2、第二步,Q对象以查问参数形式应用,多个Q对象是and关系:Test.objects.filter(Q(date=’2018-10-10 00:00:00’),Q(name__startswith=’h’) | Q(name__startswith=’p’) ...

June 28, 2022 · 1 min · jiezi

关于django:Django-如何获取-Model-字段列表

在平时的开发过程中,防止不了须要获取 Model 中的字段列表。 那须要把所有字段都再复制一份吗?这样的话就太麻烦了,而且前期也不好保护。 其实,Django 内置了一个办法,能够很轻松解决这个问题。 上面以 User 表举一个例子。 >>> from django.contrib.auth.models import User>>> User._meta.get_fields()(<ManyToOneRel: admin.logentry>, <django.db.models.fields.AutoField: id>, <django.db.models.fields.CharField: password>, <django.db.models.fields.DateTimeField: last_login>, <django.db.models.fields.BooleanField: is_superuser>, <django.db.models.fields.CharField: username>, <django.db.models.fields.CharField: first_name>, <django.db.models.fields.CharField: last_name>, <django.db.models.fields.EmailField: email>, <django.db.models.fields.BooleanField: is_staff>, <django.db.models.fields.BooleanField: is_active>, <django.db.models.fields.DateTimeField: date_joined>, <django.db.models.fields.related.ManyToManyField: groups>, <django.db.models.fields.related.ManyToManyField: user_permissions>)通过 get_fields() 办法会返回一个 tuple,每个元素都是 model field 类型。 这个后果并不是咱们想要的,咱们须要的是字段名称列表。只须要对每个 field 字段取 name 属性就能够了。 >>> [field.name for field in User._meta.get_fields()]['logentry', 'id', 'password', 'last_login', 'is_superuser', 'username', 'first_name', 'last_name', 'email', 'is_staff', 'is_active', 'date_joined', 'groups', 'user_permissions']这样就能够了。 ...

May 6, 2022 · 1 min · jiezi

关于django:Django-Model-如何返回空的-QuerySet

>>> from django.contrib.auth.models import User>>> User.objects.none()<QuerySet []>以上就是本文的全部内容,如果感觉还不错的话,欢送点赞,转发和关注,感激反对。 举荐浏览: 计算机经典书籍技术博客: 硬核后端开发技术干货,内容包含 Python、Django、Docker、Go、Redis、ElasticSearch、Kafka、Linux 等。Go 程序员: Go 学习路线图,包含根底专栏,进阶专栏,源码浏览,实战开发,面试刷题,必读书单等一系列资源。面试题汇总: 包含 Python、Go、Redis、MySQL、Kafka、数据结构、算法、编程、网络等各种常考题。

May 5, 2022 · 1 min · jiezi

关于django:UMEM友盟统计自定义事件多应用一键同步-批处理工具

性能预览点击预览线上部署的测试版本 1、请勿压测,倡议应用 chrome浏览器;2、目前【工作治理】的socket连贯不是并发的(因为我比拟菜...),如果多人同时拜访可能须要排队期待,同时这是提供预览的;3、在线上预览版本注册的账号后续可能会革除,正式应用请用docker部署到本地;前言现有产品用的友盟统计。 免费版的友盟统计每个利用最多只能有500个无效的自定义事件,超过最大数量后如果想要新增,则须要先暂停一些不罕用或者已废除的自定义事件才行。在友盟官网,是有“批量暂停”操作的,但其“批量暂停”跟“筛选性能”是离开的,导致我不能筛选合乎本身需要的一些事件进行暂停。 其次,有的时候产品改版,性能形容可能发生变化,须要批改自定义事件的显示名称,想要批改友盟自定义事件显示名称的话,则须要一个id一个id地搜寻,而后一个一个地批改。如果变更的自定义事件过多或者变更次数比拟频繁,那这样机械的操作就挺繁琐的。尽管友盟官网有批量上传自定义事件性能,然而已存在的自定义事件id不会进行更新,而是被疏忽掉,所以要想更新显示名称,还是得一个一个地查找能力更新。 另外,如果同一个产品有多个包名(多马甲),外面的自定义事件根本都是一样的,照下面所述状况,如果有性能差不多&自定义事件统一的利用A、利用B、利用C,则须要机械地来回操作屡次,这真是一件耗时耗力的事件,一次两次还好,但如果操作次数多了,每次都须要繁琐的关上官网进行一些必要而干燥的操作,心里总会有一些马儿在奔流。 所以,就下面遇到的问题,我多心愿有个工具可能解决我的痛点,于是我施展本人的强项:百度 & google & cv,一直输出“友盟批处理工具”、“友盟自定义事件批量治理”、“友盟助手”等关键词,翻了几页之后没有找到合乎本人需要的工具,有些悲观。起初我就想,要不本人写代码实现这样的批处理操作好了。于是我花了一天工夫,剖析友盟自定义事件操作api,写了一个python脚本,根本满足了本人的需要: 1、读取友盟自定义事件模板文件,存在则更新,不存在则插入;2、缓存友盟自定义事件列表到本地,依据筛选指定事件进行暂停操作,实现筛选并批量暂停;3、实现将“利用A”的自定义事件状态,批量复制(同步)到“利用B”、“利用C”上。前面一段时间,我都是间接执行这个脚本来实现相应操作的。一开始本人还算比较满意,然而操作次数多了,感觉还是比拟繁琐(人的欲望与需要总是无穷无尽啊),因为有时候友盟那边的cookie生效了,还得关上我的项目手动更新文件外面的配置项,另外就是筛选条件的配置项也得批改配置文件。所以我又想着,能不能自己写一个web治理页面呢(因为我现主业务是搞Android的)?联合本人的应用习惯再顺便加点性能。 于是我便开始web治理页面的开发了。取名 UMEM。 技术选型最早最早我想着用 Flask + html 来写的,次要我之前用Flask写过一些小api还算比拟相熟(只是相熟简略利用,囫囵吞枣不精通)。不过最终还是选用了Django + vue3作为开发脚手架,这哥俩我也是第一次接触,因为只是要做个小工具,所以利用空闲工夫边学边做对于我来说也算是两全其美。而且vue的教程目前也很多,饿了么的element-plus(vue3) 提供的界面控件也很合乎目前开发的需要。 开发历程因为后面曾经用python脚本实现了基本功能,所以在web端上,一开始我只是心愿: 1、操作更加便捷,比方上传自定义事件文件我想要简略的拖拽就行;2、执行友盟自定义工作事,心愿及时看到相应的操作日志及进度;3、自定义事件有专门的筛选条件不便检索;以上性能都逐个(通过各种搜寻 & 各种cv)解决了,在后续开发过程中,因为须要操作的友盟利用还是须要本人手动输出key、友盟的cookie过期后还是得本人复制粘贴进行更新,所以本人持续追加了新需要: 1、心愿间接从已有的友盟利用列表中抉择须要操作的利用,而不是本人手动输出利用key;2、友盟的cookie可能一键更新,缩小繁琐的复制粘贴操作;第一个需要点容易解决,第二个需要点我一开始是想通过程序模仿申请友盟api来获取cookie,然而那样又须要账号密码,同时还得解决登录前的一个验证码校验,所以这个计划不太行。正好我看到一些谷歌浏览器插件能够更新cookie(一些可将文章批量更新各大平台的产品的从属插件),我便进行海量搜寻&模拟着写一个合乎本人需要的谷歌浏览器插件,这个插件可能一键更新友盟的cookie信息,于是便有了UMEM-友盟登录助手 一键更新配置,免去手动复制粘贴之劳形。点击下载插件 再起初,思考到在局域网内部署供多人应用,于是追加了注册登录性能。 在性能都开发得差不多的状况下,我将程序打包为docker镜像,不便一键部署到本地或者近程服务器。 运行docker镜像1、创立本地目录,用于挂载docker运行时的log目录、数据库(这小工具数据库目前应用的是sqlite3) mkdir -p ~/umem/logmkdir -p ~/umem/db2、运行 docker ( -e LANG=C.UTF-8 是解决python解决中文的问题, 这里的/home/samge/umem是对应宿主机的绝对路径,须要更换为上一步本人理论创立的本地目录 ): docker run -d \-v /home/samge/umem/db:/app/db \-v /home/samge/umem/log:/app/log \-p 8000:8000 \-p 9001:9001 \--name umem \--pull=always \--restart always \-e LANG=C.UTF-8 \samge/umem:v1拜访UMEM拜访地址:http://localhost:8000 Supervisor治理页面:http://localhost:9001/ Supervisor账号:adminSupervisor明码:admin点击预览线上部署的测试版本 (请勿压测,倡议应用 chrome浏览器,目前【工作治理】的socket连贯不是并发的,如果多人同时拜访可能须要排队期待,同时这是提供预览的,注册的账号后续可能会革除,尽量本人用docker部署到本地应用) 应用1、注册账号登录2、进入“配置管理”页,配置友盟登录后的cookie等相干信息,这里可应用 UMEM-友盟登录助手 一键更新配置3、在“友盟key”页,抉择须要操作的友盟利用4、配置实现,可进行测试/应用相干截图 ...

February 20, 2022 · 1 min · jiezi

关于django:用Django写一个简易的漫画网站

用Django写一个繁难的漫画网站玩爬虫的时候,喜爱用它来爬漫画。漫画爬到手了,然而没有分类,找起来挺麻烦的,浏览体验感也不好,于是就想写一个简略的漫画网站 源码传送门 一些唠叨为什么要写漫画网站,为什么不必治理漫画的软件 想写漫画网站次要还是想通过一个开发的过程去理解它们是怎么做到业务解决与交互的。用实际的形式搞清楚一些原理与逻辑。目前还在学习阶段,应用漫画管理软件不利于晋升本人的学习能力。再说这个我的项目也是拿来练练手的哈哈哈。 相干技术前端框架:Bootstrapweb框架:Django数据库:MySQL运行环境与工具 编译器: pycharmpython3.8这个我的项目没有采纳前后端拆散的形式,所以真的是简略漫画网站 网站性能瀑布式浏览搜寻分类目录后盾治理效果图如下(界面也非常简单) 首页: 漫画详情页: 搜寻: 搜寻后果: 漫画内容: 后盾治理: 分类管理: 章节治理: 我的项目详情目录构造comicweb │ manage.py ├─comic │ │ admin.py │ │ apps.py │ │ models.py │ │ tests.py │ │ urls.py │ │ views.py │ ├─static │ │ └─comic │ │ ├─css │ │ ├─fonts │ │ └─js ├─comicweb │ │ asgi.py │ │ settings.py │ │ urls.py │ │ wsgi.py └─templates │ base.html └─comic │ category_list.html │ chapter_src.html │ comic_chapter_list.html │ errors.html │ index.html │ results.html数据关系模型 ...

January 26, 2022 · 2 min · jiezi

关于django:如何设计一套积分系统附django开源模块

调研发现任何一款有背景的app都离不开积分零碎,甚至有的app自身就是积分零碎!本文将重点介绍开源积分框架vcoin,以及应用形式价值体系作为集体开发者或者公司经营的产品,都离不开价值体系,更间接一点的就是微信支付宝领取性能,还有积分兑换礼品,次要为了裂变和营销,如果你的产品中没有价值体系,只能靠广告变现了,所以价值体系很重要 vcoin是个什么鬼vcoin是最近刚开源的django模块,开发语言是python;间接应用pip install就能够实现装置应用!整个积分零碎与业务齐全隔离,下层业务逻辑在须要积分的增删改查解冻回退等操作的时候,间接调用积分零碎静态方法即可!如果你有很多app或者产品,这一套是能够有限复用的! 应用形式=====django-vcoin ===== django-vcoin project is coin application for hehuoya.com virtual coin for app Quick startAdd "vcoin" to your INSTALLED_APPS setting like this:: INSTALLED_APPS = [ ... 'vcoin',] Include the class in your project views.py like this::from vcoin.Checker import HHYAESfrom vcoin.views import VCoinManagerand then pass your user token for vcoin aes_encrypt_data = HHYAES.aes_encrypt(utoken.decode(encoding='utf-8'))utoken = base64.b64encode(aes_encrypt_data.encode('utf-8'))VCoinManager.freezeCoin(utoken, 50, 1) Run python3 manage.py makemigrations vcoin to create the vcoin models.Run python3 manage.py migrate to create the vcoin models.Start the development server and visit http://127.0.0.1:8000/admin/to create a models if needed (you'll need the Admin app enabled).demo: ...

January 9, 2022 · 1 min · jiezi

关于django:使用-Django-搭建后台-API-服务一

开发环境IDE:Pycharm 2021.1.1零碎:macOS Mojave 10.14.6Python 3.9.2 环境筹备装置 Python略 装置 Djangopip3 install Djangopip3 install djangorestframework创立我的项目django-admin startproject api创立利用python3 manage.py startapp pms编辑 api/settings.py INSTALLED_APPS = [ ... 'rest_framework', 'pms.apps.PmsConfig']应用 MySQL 数据库装置 MySQL 驱动pip3 install mysqlclient批改配置编辑文件 api/settings.py # settings.pyDATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'pms', 'HOST': 'localhost', 'PORT': '3306', 'USER': 'root', 'PASSWORD': '123' }}批改时区编辑文件 api/settings.py TIME_ZONE = 'Asia/Shanghai'执行数据库迁徙# 迁徙数据库python3 manage.py migrate# 创立超级管理员python3 manage.py createsuperuser创立模型编辑 pms/models.py from django.db import modelsclass Project(models.Model): name = models.CharField(max_length=100) start_date = models.DateField end_date = models.DateField# 生成迁徙文件python3 manage.py makemigrations pms# 查看对应的迁徙 SQLpython3 manage.py sqlmigrate pms 0001# 执行迁徙(模型同步到数据库)python3 manage.py migrate创立序列化新建 pms/serializers.py,编辑: ...

December 23, 2021 · 1 min · jiezi

关于django:关于Pythondocx操作excel的一些记录

背景最近在做客户端性能测试的提效工作,会把以后版本的性能数据与上个版本的性能数据进行比照,而后把比照论断以及数据,放到docx文档上,主动生成一个性能报告,就学习了相干Python-docx的相干操作,记录如下。 根本介绍python-docx 是用于创立可批改 微软 Word 的一个 python 库,提供全套的 Word 操作,是最罕用的 Word 工具。能够对文档进行更改,蕴含段落、分页符、表格、图片、题目、款式等简直所有的word文档中能罕用的性能都蕴含了。只能解析docx文件,解析不了doc文件。python-docx将整个文章看做是一个Document对象,其根本构造如下: 每个Document蕴含许多个代表“段落”的Paragraph对象,寄存在document.paragraphs中每个Paragraph都有许多个代表"行内元素"的Run对象,寄存在paragraph.runs根本的一些应用from docx import Document as Docfrom docx.document import Documentimport osdoc: Document = Doc()word_path = os.getcwd()doc.save(os.path.join(word_path, 'demo.docx'))下面代码,咱们引入python-docx 最外围的对象Document,它对应的就是一个word文件,能够通过这个对象来操作word里的所有内容。 题目doc.add_heading(text="一级题目", level=1)doc.add_heading(text="二级题目", level=2)text参数制订题目的文字,level制订题目的级别,一级题目还是二级题目,如果level等于0,题目就会当做文档的title,level反对1-9个级别。 段落doc.add_paragraph("测试段落一")paragraph = doc.add_paragraph() paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTERrun = paragraph.add_run("测试段落二")run.bold = Truerun.font.name = u'宋体'增加段落有两种形式,如上:应用doc.add_paragraph("测试段落一")间接增加,另一种通过add_run来增加,同时能够操作文字的各种属性,比方粗体、字体、色彩等等 本文重点操作表格创立table = doc.add_table(2, 3, style="Table Grid")调用add_table办法,并传入行数和列数,即可实现一个表格的创立,如下图: 增加表头['场景', '版本', '内存', 'CPU', '卡顿数', 'GPU']假如咱们的表头内容寄存再这样一个列表中 columns = ['场景', '版本', '内存', 'CPU', '卡顿数', 'GPU']table = doc.add_table(1, len(columns), style="Table Grid")for i in range(len(columns)): row = table.rows[0] row.cells[i].text = columns[i]依据表头的长度来确定表格有多少列,目前咱们还不晓得有多少行,就只须要增加一行就能够。 ...

December 11, 2021 · 1 min · jiezi

关于django:AttributeError-Settings-object-has-no-attribute-HBase

django 自定义配置报错: AttributeError: 'Settings' object has no attribute 'HBase'如果咱们须要用到 Hbase 的话,能够仿照 Mysql 一样,把相干的信息配置写入到 settings 文件中,然而我遇到了一个问题,就是无奈导入。 In [12]: settings.HBASE---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-12-22bd47148938> in <module>----> 1 settings.HBASE~\.virtualenvs\twitter-5Z0qCgub\lib\site-packages\django\conf\__init__.py in __getattr__(self, name) 81 if self._wrapped is empty: 82 self._setup(name)---> 83 val = getattr(self._wrapped, name) 84 85 # Special case some settings which require further modification.AttributeError: 'Settings' object has no attribute 'HBASE'In [13]: settings.HBase---------------------------------------------------------------------------AttributeError Traceback (most recent call last)<ipython-input-13-1ee0306304e8> in <module>----> 1 settings.HBase~\.virtualenvs\twitter-5Z0qCgub\lib\site-packages\django\conf\__init__.py in __getattr__(self, name) 81 if self._wrapped is empty: 82 self._setup(name)---> 83 val = getattr(self._wrapped, name) 84 85 # Special case some settings which require further modification.AttributeError: 'Settings' object has no attribute 'HBase'后果问题的排查发现,在 Django 的配置文件 settings 中,必须应用全副大小能力被导入。 ...

November 4, 2021 · 2 min · jiezi

关于django:django-orm-如何在字段的默认值同步显示在表定义语言DDL中

sqlalchemy 提供了 server_default 来实现题目中的性能,然而 Django 的 ORM 貌似没有提供相似的性能。 class Bank(BaseModel): __tablename__ = 'bank' id = Column(Integer, primary_key=True) name = Column(String(255), unique=True, nullable=False) is_deleted = Column(BOOLEAN, default=0, server_default=text('0')) created_at = Column('created_at', TIMESTAMP, nullable=False, server_default=func.now()) deleted_at = Column('deleted_at', TIMESTAMP, nullable=False, server_default=text("'1970-01-01 00:00:01'"))通过互联网,我查问到有如下的解决方案:https://cloud.tencent.com/dev... 我想晓得有更优雅的解决方案吗?

October 30, 2021 · 1 min · jiezi

关于django:如何高效的开展客户端的性能测试

APP性能测试是什么从网上查了一下,貌似也没什么特地的定义,我这边依据本人的教训给出一个本人的定义,如有偶合纯属雷同。 客户端性能测试就是,从业务和用户的角度登程,设计正当且无效的性能测试场景,制订各性能场景下的客户端性能指标(内存、CPU、卡顿数、帧率、电量、加载时长等),并制订规范化的执行流程,依照执行规范执行性能场景同时使用性能测试具收集性能数据,并对数据进行剖析,如果有性能问题并对问题进行定位,配合开发进行修复验证公布,最初输入残缺的性能报告。 从下面的定义中,咱们能够得出,在APP的性能测试须要关注以下几方面,性能测试的场景的设计、性能指标的定义、规范化的执行流程、性能数据数据收集、性能数据分析、性能问题定位、性能测试报告。 性能测试并不是说咱们上来找个工具,轻易跑个场景,拿到数据,输入个报告,就能够了。每一步都应该做到对症下药,从而体现出测试人员的专业性。 APP性能测试怎么做上面咱们别离来看一下: 性能测试场景的设计 场景可能是一个操作的一直反复,也可能是几个操作的组合再反复,对于性能测试的场景来说,他肯定有反复的操作或者继续的操作,目标是通过反复或者继续的操作,把性能问题放大到肯定水平,可能让咱们发现问题。 举个栗子:以B站举荐tab为例,想测试feed滑动状况下的性能体现,那性能场景能够设计成,feed滑动50次,每次滑动距离2s。 性能指标的定义 常见的挪动端性能指标有:内存、cpu、帧率、卡顿数、wakp up数、展现时长等,关注什么性能指标是依靠于咱们的性能测试场景。 举个栗子:以B站举荐tab为例,当咱们冷启APP进入举荐tab的时候,更关注数据展现时长,滑动场景更关注卡顿数,为不同场景设计正当的性能指标也是咱们须要认真思考的。 规范化执行流程 场景和指标都定义好了当前,就要开始执行了,这里要求要规范化执行,规范化执行不是简略的依照场景的定义去执行就好,而是要有很多关注的点。 能够定义的标准有哪些: - 场景开始执行前须要期待多少s- 执行后须要期待多少s- 每次测试需不需要冷启或是必须重新安装- 装置好须要期待多久才能够开始测试- 测试账号、测试数据、设施、网络需不需要固定 每一个点都可能影响的性能数据的准确性,必须要定义标准,每次都要按着标准去执行,而且这个标准是动静,随着咱们一直的测试,会发现很多影响性能数据的问题,都必须定制标准,加以躲避。同时好的标准可能未咱们前面进行性能数据分析打下基础。 性能数据数据收集性能数据收集可能是整个客户端性能测试中最简略的局部了,有成熟的工具perfdog能够应用,不便简略,也能够应用商业化的perfdog service实现自动化的性能数据收集,就是须要花钱。 性能数据分析在收集到性能数据之后,就要去剖析数据,如何剖析,上面我简略说一下,前面会出文章专门说如何对性能数据进行剖析 走势图,从走势图上咱们大抵能够看出该场景在以后版本的性能体现,能够得出以下论断: 和之前版本的走势图进行比照,性能指标的稳定状况性能指标峰值、场景的均值以及涨幅的变动场景的起始值与之前版本的变动场景完结后的值与之前版本的变动性能问题定位在进行完性能数据分析当前,如果有问题,就须要去定位问题是那一块业务的问题或者是哪一个mr引起的问题,就须要回溯。 先找开发,和开发沟通一下,看是否依据问题表象确定问题,如果确认不了,就须要测试定位是哪个mr合入引起的列出本次版本合入所有mr,筛选出那些mr是性能问题所在的业务找mr合入前后的包从新跑,确认每个mr是否有影响当确定是哪个mr合入引起的性能问题后,再次和开发沟通性能测试报告性能测试报告的目标是给出以后版本的性能体现状况,须要蕴含一些外围的模块 测试论断性能问题归因各个场景的性能指标数据测试环境以及计划各个场景的性能指标走势图以上我对app性能测试的一些浅显了解和教训,有问题能够留言,一起探讨。。 欢送大家拜访我的博客,有更多对于客户端性能测试、自动化测试的内容, 博客地址

August 31, 2021 · 1 min · jiezi

关于django:从0开始自研一套iOS分发系统

原理 1,对使用者来说就是一个ipa上传到散发零碎,而后下载即可2,散发零碎拿到ipa,解析外面的内容,拼接出下载地址即可下载地址构造:‘itms-services:///?action=download-manifest&url=plist下载门路’,ipa的实在下载地址都在plist文件里,只能通过这种连贯应用safari浏览器能力下载 开发过程服务端开发1,选中一种语言(php、Java、Node.js、Django、Go等)服务器语言都能够,我这里选用的是python的Django框架大家web服务器,应用docker治理所有服务,先简略搭建一个界面: 2,写一个上传ipa的接口upload,接管到ipa之后,很多实现计划是间接解压,这种效率不太好,python能够应用zipfile,无需解压即可读取内容,ipa实质上你能够了解为就是一个zip文件,解压后就能够失去实在内容 3,进入ipa文件外部之后,先拿到info.plist文件,这个文件比拟重要,外面能够解析进去包名、版本号、build号、最小支持系统版本号等,根本各种根底信息都有,我这里应用plistlib将info.plist加载到字典对象中进行解析 4, 而后也是遍历ipa中的文件,找到利用图标,保留到static下(这里的图片有问题,后续解说解决方案) 5,如果有获取所有测试机udid信息,须要遍历出embedded文件,而后解析即可,然而这里的解析只能字符串解析,除非你是间接跑在mac电脑上的脚本,能够应用mac自带的security进行转化为xml格局,有点麻烦 6,拼接下载用的plist文件,能够轻易打一个空我的项目获取一个当模板我这里大略是这样的: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>items</key> <array> <dict> <key>assets</key> <array> <dict> <key>kind</key> <string>software-package</string> <key>url</key> <string>%sstatic/upload/%s</string> </dict> </array> <key>metadata</key> <dict> <key>bundle-identifier</key> <string>%s</string> <key>bundle-version</key> <string>%s</string> <key>kind</key> <string>software</string> <key>title</key> <string>%s</string> </dict> </dict> </array> </dict> </plist>把ipa的下载地址和bundle信息等拼接到外面即可 7,最初就是下载地址拼接 download_url = 'itms-services://?action=download-manifest&url=你的plist地址'这个下载地址放到a标签或者事件执行的外面即可,一旦拜访就是申请下载,能够间接复制到浏览器验证 另外须要留神,plist地址和ipa地址肯定要是https的,这是苹果的限度到这里一套简略的iOS散发零碎就实现了,开发过程中遇到一个疑难问题这里讲一下 疑难问题解决方案这里说的疑难问题其实就是图标的展现,你会发现间接应用ipa外面导出来的app图标在safari上能够展现,然而在其余浏览器上展现不进去。正如我下面的截图那样;起因是苹果在打包的时候会对所有图片进行压缩优化,失常的一个icon是130K这样,达到ipa外面也就30K,这也阐明了有人对png进行压缩来优化包体积,然而最终出包的时候发现包体并未减小的起因。 怎么解决这个图片问题1,依据问题搜寻到pngdefry这个工具,是一个大神十几年前应用c写的,通过一番摸索发现,有python版本的然而下载安装失败,有一台机器下载胜利了然而不反对python3,应用命令行形式测试,发现的确能够解决这个问题。命令:pngdefry -s _test a.png ,这句命令是把图标a.png还原为a_test.pngpngdefry有node版本的,没测试node是不是好的,然而不反对python只能放弃 2,pngdefry计划看来是行不通的,反正我是搞了一天也没胜利。持续摸索发现mac自带pngcrush命令也是解决这个问题的,应用形式: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/pngcrush -revert-iphone-optimizations -q Local.png Local-standard.png能够看出这个命令是xcode里带的,通过-revert-iphone-optimizations 来还原图片;不同人的xcode地址可能不是这个,能够应用xcode-select -print-path 找到xcode门路。这个工具通过测试也的确能解决图片展现问题,然而pyhton不反对啊,服务器不反对啊,只反对mac而且还得找门路,果决放弃 3,通过一通的google和github探寻他人的计划,没找到后果,忽然想到咱们公司有人用node写了一套,于是去打包机看了一眼,居然又是一种新形式应用的sips -s format png 压缩的图标门路 --out 还原的图片门路可悲的是这个sips命令也是mac自带的命令 ...

August 22, 2021 · 1 min · jiezi

关于django:平台登录过程

牢记:前端拜访某一url,只是通过该url拜访到对应的视图函数,并依据传来的数据(参数、body,request申请头中的各种数据等)获取后端的资源或数据。 筹备条件:1.理解http的状态码:https://developer.mozilla.org...2.理解django的调用过程:3.django中间件相干: 'django.contrib.sessions.middleware.SessionMiddleware', -- session相干'django.contrib.auth.middleware.AuthenticationMiddleware'--认证相干登录过程:申请http://xx/login/?next=/index/,GET申请--获取登录界面,POST申请 -- 传递用户信息(邮箱和明码)认证user = auth.authenticate(username=email,password=password)依据settings.py中的AUTHENTICATION_BACKENDS来确定认证模块列表,顺次认证,认证通过则进行;认证后端默认是['django.contrib.auth.backends.ModelBackend']。认证后端类必须实现两个办法:get_user(user_id)和authenticate(request, **credentials)申请相干接口,获取用户信息,将request body中的信息和用户信息比照;认证通过后,返回user信息;将用户信息保留至session中,并设置COOKIE。auth.login(request,user) -- Persist a user id and a backend in the request. This way a user doesn't have to reauthenticate on every request.如果COOKIE中的session过期,则重定向到登录界面;

August 16, 2021 · 1 min · jiezi

关于django:Django常用配置

创立Django我的项目(命令行)创立我的项目:关上终端,应用命令:django-admin startproject [项目名称]即可创立。比方:django-admin startproject first_project。 创立利用(app):python manage.py startapp [app名称] 我的项目文件配置在settings.py中批改如下代码段 创立数据库# 进入数据库C:\Users\leo>mysql -uroot -p# 输出明码Enter password: **********# 创立数据库并设定字符集mysql> create database GPAXF charset=utf8;Query OK, 1 row affected (0.01 sec)# 创立能够让Django读取的数据mysql> grant all privileges on GPAXF.* to leo@'%' identified by '1q2w3E!';Query OK, 0 rows affected, 1 warning (0.04 sec)mysql> flush privileges;Query OK, 0 rows affected (0.04 sec)截图如下所示: 配置数据库DATABASES = { 'default': { # 数据库引擎(是mysql还是oracle等) 'ENGINE': 'django.db.backends.mysql', # 数据库的名字 'NAME': 'GPAXF', # 连贯mysql数据库的用户名 'USER': 'leo', # 连贯mysql数据库的明码 'PASSWORD': '1q2w3E!', # mysql数据库的主机地址 'HOST': '127.0.0.1', # mysql数据库的端口号 'PORT': '3306', }}pycharm连贯数据库 ...

August 1, 2021 · 1 min · jiezi

关于django:drf使用1序列化视图

介绍drf框架是基于Django框架,用于疾速构建Web RESTful API的工具官网文档:https://www.django-rest-framework.org/ 装置:pip install djangorestframework 疾速应用1. 搭建模型from django.db import modelsclass BookModel(models.Model): """ 书籍模型 """ name = models.CharField(max_length=200, verbose_name='书籍名称') book_info = models.TextField(max_length=1024, default=None, blank=True, verbose_name='书籍介绍') create_time = models.DateTimeField(auto_now_add=True, verbose_name='创立工夫') class Meta: db_table = 'tb_book' verbose_name = '书籍信息' verbose_name_plural = verbose_nameclass HeroModel(models.Model): """ 书籍人物模型 """ name = models.CharField(max_length=200, verbose_name='英雄姓名') hero_info = models.TextField(max_length=1024, default=None, blank=True, verbose_name='英雄介绍') join_time = models.DateTimeField(auto_now_add=True, verbose_name='退出工夫') book_name = models.ForeignKey('BookModel', on_delete=models.CASCADE, related_name='book_hero', verbose_name='所属书籍') class Meta: db_table = 'tb_hero' verbose_name = '书籍人物信息' verbose_name_plural = verbose_name留神外键对应关系2. setting配置INSTALLED_APPS = [ ...... 'rest_framework',]3. 序列化器serializer# serializers.pyfrom rest_framework import serializersfrom .models import BookModel, HeroModelclass BookSerializer(serializers.ModelSerializer): class Meta: model = BookModel fields = '__all__'4. 视图views# views.pyfrom rest_framework.viewsets import GenericViewSetfrom rest_framework.mixins import ListModelMixin, CreateModelMixinfrom .serializers import BookSerializerfrom .models import BookModelclass Books(GenericViewSet, ListModelMixin, CreateModelMixin): queryset = BookModel.objects.all() serializer_class = BookSerializer5. 路由主动注册DefaultRouterfrom rest_framework.routers import DefaultRouterfrom . import viewsapp_name = 'book'urlpatterns = []router = DefaultRouter()router.register('book', views.Books, basename='book')urlpatterns += router.urls6. 成果显示 ...

August 1, 2021 · 2 min · jiezi

关于django:unittest框架命令行参数详解一

-b,--buffer在执行测试case时,如果case胜利则case在执行过程中输入的内容不会被显示进去,如果失败则会。 class TestLogin(unittest.TestCase): def test_login_by_password(self): a = 2 print("这是运行胜利时的输入") assert a == 1 + 1如果没有-b参数,case执行胜利时是有打印语句输入的内容 如果加了-b参数就没有这个输入。 如果有-b参数,然而case运行失败,则这个输入还是会有的 -b参数还是比拟有用的,当case执行成,其实是不关怀这些输入的内容,只有在失败的时候才会看这些。 -c,--catch在执行case的过程中,如果按下command+c或control+c,用例不会立刻进行而是期待以后的case运行实现并且输入测试后果后才中断程序,这个时候如果再次按下command+c或control+c,才会立刻终止程序,并抛出KeyboardInterrupt异样。 class TestLogin(unittest.TestCase): def test_login_by_password(self): b = 5 a = 2 time.sleep(4) print("这是运行胜利时的输入") assert a == 1 + 1 def test_login_by_sms(self): print('这是test_login_by_sms') assert 2 == 2 def tearDown(self) -> None: print("这是tearDown")我在下面的代码中加了teardown,来试试,试试试试。 看控制台的输入,曾经输出了command+c,然而这条case还是执行结束了。 如果没有有这个参数的话,间接按下command+c或control+c程序会立刻进行,这时就会导致一个问题,teardown就不会执行了,比方teardown外面有一些数据清理、资源开释的操作,这些如果不解决可能会导致系统呈现一些问题。那么此时就能够加上这个参数,保障teardown是能够被执行到的。 -f,--failfast当呈现第一个谬误或者case失败时,进行运行其余测试用例。这个参数个别是在咱们刚写好用例进行调试的时候能够应用,而在有定时工作执行case的时候则不能应用。 还是用下面那个例子,咱们让第一个case失败,而后看看运行状况。 这里就只运行了一个测试用例,另一个没有执行。 --locals简略写个用例 class TestLogin(unittest.TestCase): def test_login_by_password(self): b = 5 a = 3 print("这是运行胜利时的输入") assert a == 1 + 1当测试运行失败时会输入case中所有的局部变量。 ...

July 25, 2021 · 1 min · jiezi

关于django:ContentType-header-is-texthtml-not-applicationjson

报错DRF运行报错 ValueError: Content-Type header is "text/html", not "application/json" ----------------------------------------------------------------------Traceback (most recent call last): File "C:\Users\17293\Desktop\Coder\Python\Django\twitter\newsfeeds\api\tests.py", line 41, in test_list print(response.json()) File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\django\test\client.py", line 662, in _parse_json raise ValueError(ValueError: Content-Type header is "text/html", not "application/json"----------------------------------------------------------------------Ran 1 test in 0.362sFAILED (errors=1)Destroying test database for alias 'default'...报错起因和解决办法:去 urls.py 文件中增加路由配置

July 10, 2021 · 1 min · jiezi

关于django:Custom-models-display-ordering-for-Django-admin-dashboard

Django AdminBy default, it displays all the apps in INSTALLED_APPS that have been registered with the admin application, in alphabetical order. https://docs.djangoproject.com/en/3.1/intro/tutorial07/#customize-the-admin-index-page def get_app_list(self, request): """ Return a sorted list of all the installed apps that have been registered in this site. """ app_dict = self._build_app_dict(request) # Sort the apps alphabetically. app_list = sorted(app_dict.values(), key=lambda x: x['name'].lower()) # Sort the models alphabetically within each app. for app in app_list: app['models'].sort(key=lambda x: x['name']) return app_listhttps://github.com/django/django/blob/8bca838f4a230b78dd44fc1db3c1b81e444c6099/django/contrib/admin/sites.py#L501There are multiple ways to achieve this on the internetAdding a numeric prefix for each verbose_name_plural in App Model MetaOverride admin/base.html tempalteOverride AdminSite class and get_app_list() methodFor this article, I will be using a way that to override the get_app_list class method only without overriding the class. ...

June 30, 2021 · 2 min · jiezi

关于django:Django-单元测试报错没有创建数据表

报错形容报错如下 > python manage.py test tweets.............. File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\utils.py", line 90, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\utils.py", line 84, in _execute return self.cursor.execute(sql, params) File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\backends\mysql\base.py", line 73, in execute return self.cursor.execute(query, args) File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\MySQLdb\cursors.py", line 206, in execute res = self._query(query) File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\MySQLdb\cursors.py", line 319, in _query db.query(q) File "C:\Users\17293\AppData\Local\Programs\Python\Python39\lib\site-packages\MySQLdb\connections.py", line 259, in query _mysql.connection.query(self, query)django.db.utils.ProgrammingError: (1146, "Table 'test_d_twitter_db.tweets_tweet' doesn't exist")PS C:\Users\17293\Desktop\Coder\Python\Django\twitter> python .\manage.py makemigrations数据表是单元测试本人创立的,是不是手动创立的所以这个报错一开始让我摸不着头脑 ...

June 25, 2021 · 1 min · jiezi

关于django:小白学Python使用Django实现商城邮箱验证功能

增加邮箱后端逻辑1. 增加邮箱接口设计和定义1.申请形式选项计划申请办法PUT申请地址/emails/2.申请参数参数名类型是否必传阐明emailstring是邮箱3.响应后果:JSON字段阐明code状态码errmsg错误信息2. 增加邮箱后端逻辑实现class EmailView(View): """增加邮箱""" def put(self, request): """实现增加邮箱逻辑""" # 接管参数 json_dict = json.loads(request.body.decode()) email = json_dict.get('email') # 校验参数 if not email: return http.HttpResponseForbidden('短少email参数') if not re.match(r'^[a-z0-9][\w\.\-]*@[a-z0-9\-]+(\.[a-z]{2,5}){1,2}$', email): return http.HttpResponseForbidden('参数email有误') # 赋值email字段 try: request.user.email = email request.user.save() except Exception as e: logger.error(e) return http.JsonResponse({'code': RETCODE.DBERR, 'errmsg': '增加邮箱失败'}) # 响应增加邮箱后果 return http.JsonResponse({'code': RETCODE.OK, 'errmsg': '增加邮箱胜利'})3. 判断用户是否登录并返回JSON重要提醒:只有用户登录时能力让其绑定邮箱。此时前后端交互的数据类型是JSON,所以须要判断用户是否登录并返回JSON给用户。计划一: 应用Django用户认证零碎提供的is_authenticated()class EmailView(View): """增加邮箱""" def put(self, request): """实现增加邮箱逻辑""" # 判断用户是否登录并返回JSON if not request.user.is_authenticated(): return http.JsonResponse({'code': RETCODE.SESSIONERR, 'errmsg': '用户未登录'}) pass计划二: ...

June 3, 2021 · 2 min · jiezi

关于django:小白学Python使用Django实现商城登录功能

用户名登录登录的核心思想,认证和状态放弃,通过用户的认证,确定该登录用户是美多商场的注册用户。通过状态放弃缓存用户的惟一标识信息,用于后续是否登录的判断。 1. 用户名登录逻辑剖析 2. 用户名登录接口设计1.申请形式选项计划申请办法POST申请地址/login/2.申请参数:表单参数名类型是否必传阐明usernamestring是用户名passwordstring是明码rememberedstring是是否记住用户3.响应后果:HTML字段阐明登录失败响应谬误提醒登录胜利重定向到首页3. 用户名登录接口定义class LoginView(View): """用户名登录""" def get(self, request): """ 提供登录界面 :param request: 申请对象 :return: 登录界面 """ pass def post(self, request): """ 实现登录逻辑 :param request: 申请对象 :return: 登录后果 """ pass4. 用户名登录后端逻辑class LoginView(View): """用户名登录""" def get(self, request): """ 提供登录界面 :param request: 申请对象 :return: 登录界面 """ return render(request, 'login.html') def post(self, request): """ 实现登录逻辑 :param request: 申请对象 :return: 登录后果 """ # 承受参数 username = request.POST.get('username') password = request.POST.get('password') remembered = request.POST.get('remembered') # 校验参数 # 判断参数是否齐全 if not all([username, password]): return http.HttpResponseForbidden('短少必传参数') # 判断用户名是否是5-20个字符 if not re.match(r'^[a-zA-Z0-9_-]{5,20}$', username): return http.HttpResponseForbidden('请输出正确的用户名或手机号') # 判断明码是否是8-20个数字 if not re.match(r'^[0-9A-Za-z]{8,20}$', password): return http.HttpResponseForbidden('明码起码8位,最长20位') # 认证登录用户 user = authenticate(username=username, password=password) if user is None: return render(request, 'login.html', {'account_errmsg': '用户名或明码谬误'}) # 实现状态放弃 login(request, user) # 设置状态放弃的周期 if remembered != 'on': # 没有记住用户:浏览器会话完结就过期 request.session.set_expiry(0) else: # 记住用户:None示意两周后过期 request.session.set_expiry(None) # 响应登录后果 return redirect(reverse('contents:index'))多账号登录Django自带的用户认证零碎只会应用用户名去认证一个用户。所以咱们为了实现多账号登录,用户名、手机号或者第三方登陆,就须要自定义认证后端,采纳其余的惟一信息去认证一个用户 ...

June 1, 2021 · 3 min · jiezi

关于django:小白学Python使用Django实现商城验证码模块

本文次要波及图形验证码的相干性能,次要包含,图形验证码获取、验证码文字存储、验证码生成等。 图形验证码接口设计和定义验证码获取接口设计 uuid作为门路参数,惟一标识验证码所属用户 新建利用验证码的相干逻辑咱们用一个独自的app解决,所以这里须要新建一个叫verifications的app,建好app后,关上views.py视图文件,编写一个验证码的视图类 class ImageCodeView(View): """图形验证码""" def get(self, request, uuid): """ :param request: 申请对象 :param uuid: 惟一标识图形验证码所属于的用户 :return: image/jpg """ pass而后配置路由 我的项目路由配置: path('', include('apps.verifications.urls')),配置app的路由 path('image_codes/``uuid:uuid``/', views.ImageCodeView.as_view()),验证码解决相干筹备工作筹备captcha扩大包 把captcha扩大包放到verifications的lib目录下,而后须要装置Python的图片解决库,pip install Pillow 筹备Redis数据库redis用来存储图片验证码上的数字,前面会用来做校验 "verify_code": { # 验证码 "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/2", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } },图形验证码后端逻辑实现class ImageCodeView(View): """图形验证码 """ def get(self, request, uuid): """ 实现图形验证码逻辑 :param uuid: UUID :return: image/jpg """ # 生成图形验证码 text, image = captcha.generate_captcha() # 保留图形验证码 # 应用配置的redis数据库的别名,创立连贯到redis的对象 redis_conn = get_redis_connection('verify_code') # 应用连贯到redis的对象去操作数据存储到redis # redis_conn.set('key', 'value') # 因为没有有效期 # 图形验证码必须要有有效期的:设计是300秒有效期 # redis_conn.setex('key', '过期工夫', 'value') redis_conn.setex('img_%s' % uuid, 300, text) # 响应图形验证码: image/jpg return http.HttpResponse(image, content_type='image/jpg')图形验证码前端逻辑Vue实现图形验证码展现1.register.js ...

May 31, 2021 · 1 min · jiezi

关于django:python实战项目练习Django商城项目之注册功能实现

设计到的前端常识我的项目的前端页面应用vue来实现部分刷新,通过数据的双向绑定实现与用户的交互,上面来看一下需要,在用户输出内容后,前端须要做一些简略的规定校验,咱们心愿在在用户输出后可能实时检测,如果有谬误可能在输入框的下方显示进去。 <li> <label>用户名:</label> <input type="text" name="username" id="user_name"> <span class="error_tip">请输出5-20个字符的用户</span></li><li> <label>明码:</label> <input type="password" name="password" id="pwd"> <span class="error_tip">请输出8-20位的明码</span></li>下面是一个用户和明码的输入框,当用户输出完用户名当前,光标来到输入框,可能实时的检测输出内容的正确性,当输出有问题的时候,在输入框的下方显示错误信息。 v-model实现数据的双向绑定,v-on进行事件绑定,v-show是管制dom显示与否,上面是退出vue后的局部代码 <li> <label>用户名:</label> <input type="text" name="username" id="user_name" v-model="username" @blur="check_username"> <span class="error_tip" v-show="error_name">[[error_name_message]]</span></li><li> <label>明码:</label> <input type="password" name="password" id="pwd" v-model="password" @blur="check_password"> <span class="error_tip" v-show="error_password">请输出8-20位的明码</span></li>用户输出的用户名和username变量绑定,光标隐没触发绑定工夫check_username,通过v-show绑定到布尔值变量error_name,来管制是否显示字符串变量error_name_message,其余的输入框都相似这种操作。 注册业务实现前端注册业务逻辑注册表单代码: <form method="post" class="register_form" > {{ csrf_input }} <ul> <li> <label>用户名:</label> <input type="text" name="username" id="user_name" v-model="username" @blur="check_username"> <span class="error_tip" v-show="error_name">[[error_name_message]]</span> </li> <li> <label>明码:</label> <input type="password" name="password" id="pwd" v-model="password" @blur="check_password"> <span class="error_tip" v-show="error_password">请输出8-20位的明码</span> </li> <li> <label>确认明码:</label> <input type="password" v-model="password2" @blur="check_password2" name="password2" id="cpwd"> <span class="error_tip" v-show="error_password2">两次输出的明码不统一</span> </li> <li> <label>手机号:</label> <input type="text" v-model="mobile" @blur="check_mobile" name="mobile" id="phone"> <span class="error_tip" v-show="error_mobile">[[ error_mobile_message ]]</span> </li> <li> <label>图形验证码:</label> <input type="text" name="image_code" id="pic_code" class="msg_input"> <img src="{{ static('images/pic_code.jpg') }}" alt="图形验证码" class="pic_code"> <span class="error_tip">请填写图形验证码</span> </li> <li> <label>短信验证码:</label> <input type="text" name="sms_code" id="msg_code" class="msg_input"> <a href="javascript:;" class="get_msg_code">获取短信验证码</a> <span class="error_tip">请填写短信验证码</span> </li> <li class="agreement"> <input type="checkbox" name="allow" id="allow" v-model="allow" @change="check_allow"> <label>批准”商城用户应用协定“</label> <span class="error_tip" v-show="error_allow">请勾选用户协定</span> </li> <li class="reg_sub"> <input type="submit" value="注 册" @change="on_submit"> {% if register_errmsg %} <span class="error_tip2">{{ register_errmsg }}</span> {% endif %} </li> </ul></form>导入vue.js和ajax申请的js库<script type="text/javascript" src="{{ static('js/vue-2.5.16.js') }}"></script><script type="text/javascript" src="{{ static('js/axios-0.18.0.min.js') }}"></script>筹备register.js文件register.js文件次要解决注册页面的交互事件,并且向服务端提交注册表单申请 ...

May 30, 2021 · 3 min · jiezi

关于django:人员与考虑了

第一章 Python语言概述 1.1 计算机根底1.1.1 计算机特点运算速度快计算精确度高具备存储和罗逻辑判断能力 haode具备自动控制能力 1.1.2 计算机罕用设置及编码二进制数二进制数制与其余数制(1)十进制(十进位计数制)(2)八进制(八进位计数制)(3)十六进制(十六进位计数制)ASCII码Unicode编码和UTF-8编码进制转换 1.1.3 计算机系统组成 计算机硬件零碎(计算机五大部件):运算器、控制器、存储器、输出设施、输出设备。运算器又称逻辑运算单元(Arithmetic Logic Unit,ALU),次要性能是对二进制编码进行算术运算及根本逻辑运算。运算后果由控制器指挥送到内存储器。控制器基本功能是从内存储器中取指令和执行指令。存储器具备记忆性能,用来保存信息。存储器的存储容量为字节,每个字节都有本人的编号,称为“地址”。计算机解决数据时,一次能够运算的数据长度称为一个“字”,一个字能够是一个字节,也能够是多个字节,1个字节等于8位,64位电脑处理器解决数据时一次能解决的最大位数为64位,也就是8个字节。内存储器间接与CPU相连接,容量小,速度快;外存储器,硬盘、磁带、光盘等。输出设施:键盘鼠标等;输出设备:显示器,打印机等; 1.1.4 操作系统性能:过程治理、存储管理、设施治理和文件治理。 1.1.5 程序设计语言第一代:机器语言由二进制0、1代码形成第二代:汇编语言第三代:高级语言C、Python、Java等第四代:非过程化语言两个典型利用:数据库查问和应用程序生成器 1.2 Python语言简介Python之父是Guido Van Rossum,Guido也爱追剧,最喜爱的一部剧是Monty Python and the Fling Circus,Python就命名于此。去年底耐不住退休生存的寂寞,退出了微软,重返工作岗位。Python是齐全面向对象的语言。函数、模块、数字、字符串都是对象。Python在执行时,首先将".py"文件中的源代码翻译成Python的byte code(字节码),而后再由Python虚拟机执行这些byte code。 1.3 Python IDLE 开发环境1.3.1 Python IDLE开发环境装置1,Windows操作系统装置python Windows下载地址2,Mac 操作系统装置Python Mac下载地址3,UNIX/LINUX 操作系统装置Python UNIX/LINUX下载地址 1.3.2 运行Python程序print("Goodbay World!")1.4 标识符和变量1.4.1 标识符和关键字标志符是用户编程时所应用的名字。标识符由能够由字母、下划线、数字组成,然而不能以数字结尾,且Python辨别大小写。关键字就是具备非凡性能的标志符。 1.4.2 常量和变量常量就是不变的量。变量的次要作用是贮存信息,Python中变量名辨别大小写。 1.5 输出及输入函数输出函数:input()输入函数:print() 输出字符串 a = input("Please input a:")b = input("Please input b:")c = a + bprint(c)输出整数 a = int(input("Please input a:"))b = int(input("Please input b:"))c = a + bprint(c)一次输出两个字符串(字符串之间用空格隔开) ...

May 17, 2021 · 1 min · jiezi

关于django:zjy

@toc 1.1 计算机根底1.1.1 计算机特点运算速度快计算精确度高具备存储和罗逻辑判断能力具备自动控制能力 1.1.2 计算机罕用设置及编码二进制数二进制数制与其余数制(1)十进制(十进位计数制)(2)八进制(八进位计数制)(3)十六进制(十六进位计数制)ASCII码Unicode编码和UTF-8编码[进制转换](https://zhuanlan.zhihu.com/p/... 1.1.3 计算机系统组成 计算机硬件零碎(计算机五大部件):运算器、控制器、存储器、输出设施、输出设备。运算器又称逻辑运算单元(Arithmetic Logic Unit,ALU),次要性能是对二进制编码进行算术运算及根本逻辑运算。运算后果由控制器指挥送到内存储器。控制器基本功能是从内存储器中取指令和执行指令。存储器具备记忆性能,用来保存信息。存储器的存储容量为字节,每个字节都有本人的编号,称为“地址”。计算机解决数据时,一次能够运算的数据长度称为一个“字”,一个字能够是一个字节,也能够是多个字节,1个字节等于8位,64位电脑处理器解决数据时一次能解决的最大位数为64位,也就是8个字节。内存储器间接与CPU相连接,容量小,速度快;外存储器,硬盘、磁带、光盘等。输出设施:键盘鼠标等;输出设备:显示器,打印机等; 1.1.4 操作系统性能:过程治理、存储管理、设施治理和文件治理。 1.1.5 程序设计语言第一代:机器语言由二进制0、1代码形成 第二代:汇编语言 第三代:高级语言C、Python、Java等 第四代:非过程化语言两个典型利用:数据库查问和应用程序生成器 1.2 Python语言简介Python之父是Guido Van Rossum,Guido也爱追剧,最喜爱的一部剧是Monty Python and the Fling Circus,Python就命名于此。去年底耐不住退休生存的寂寞,退出了微软,重返工作岗位。Python是齐全面向对象的语言。函数、模块、数字、字符串都是对象。Python在执行时,首先将".py"文件中的源代码翻译成Python的byte code(字节码),而后再由Python虚拟机执行这些byte code。 1.3 Python IDLE 开发环境1.3.1 Python IDLE开发环境装置1,Windows操作系统装置[Python Windows下载地址](https://www.python.org/downlo...2,Mac 操作系统装置[Python Mac下载地址](https://www.python.org/downlo...3,UNIX/LINUX 操作系统装置[Python UNIX/LINUX下载地址](https://www.python.org/downlo... 1.3.2 运行Python程序print("Goodbay World!")1.4 标识符和变量1.4.1 标识符和关键字标志符是用户编程时所应用的名字。标识符由能够由字母、下划线、数字组成,然而不能以数字结尾,且Python辨别大小写。关键字就是具备非凡性能的标志符。 1.4.2 常量和变量常量就是不变的量。变量的次要作用是贮存信息,Python中变量名辨别大小写。 1.5 输出及输入函数输出函数:input()输入函数:print() 输出字符串 a = input("Please input a:")b = input("Please input b:")c = a + bprint(c)输出整数 a = int(input("Please input a:"))b = int(input("Please input b:"))c = a + bprint(c)一次输出两个字符串(字符串之间用空格隔开) ...

May 17, 2021 · 1 min · jiezi

关于django:jgkalfjsklfjsd

@toc 1.1 计算机根底1.1.1 计算机特点运算速度快计算精确度高具备存储和罗逻辑判断能 haode具备自动控制能力 1.1.2 计算机罕用设置及编码二进制数二进制数制与其余数制(1)十进制(十进位计数制)(2)八进制(八进位计数制)(3)十六进制(十六进位计数制)ASCII码Unicode编码和UTF-8编码进制转换 1.1.3 计算机系统组成 计算机硬件零碎(计算机五大部件):运算器、控制器、存储器、输出设施、输出设备。运算器又称逻辑运算单元(Arithmetic Logic Unit,ALU),次要性能是对二进制编码进行算术运算及根本逻辑运算。运算后果由控制器指挥送到内存储器。控制器基本功能是从内存储器中取指令和执行指令。存储器具备记忆性能,用来保存信息。存储器的存储容量为字节,每个字节都有本人的编号,称为“地址”。计算机解决数据时,一次能够运算的数据长度称为一个“字”,一个字能够是一个字节,也能够是多个字节,1个字节等于8位,64位电脑处理器解决数据时一次能解决的最大位数为64位,也就是8个字节。内存储器间接与CPU相连接,容量小,速度快;外存储器,硬盘、磁带、光盘等。输出设施:键盘鼠标等;输出设备:显示器,打印机等; 1.1.4 操作系统性能:过程治理、存储管理、设施治理和文件治理。 1.1.5 程序设计语言第一代:机器语言由二进制0、1代码形成 第二代:汇编语言 第三代:高级语言C、Python、Java等 第四代:非过程化语言两个典型利用:数据库查问和应用程序生成器 1.2 Python语言简介Python之父是Guido Van Rossum,Guido也爱追剧,最喜爱的一部剧是Monty Python and the Fling Circus,Python就命名于此。去年底耐不住退休生存的寂寞,退出了微软,重返工作岗位。Python是齐全面向对象的语言。函数、模块、数字、字符串都是对象。Python在执行时,首先将".py"文件中的源代码翻译成Python的byte code(字节码),而后再由Python虚拟机执行这些byte code。 1.3 Python IDLE 开发环境1.3.1 Python IDLE开发环境装置1,Windows操作系统装置[Python Windows下载地址](https://www.python.org/downlo...2,Mac 操作系统装置[Python Mac下载地址](https://www.python.org/downlo...3,UNIX/LINUX 操作系统装置[Python UNIX/LINUX下载地址](https://www.python.org/downlo... 1.3.2 运行Python程序print("Goodbay World!")1.4 标识符和变量1.4.1 标识符和关键字标志符是用户编程时所应用的名字。标识符由能够由字母、下划线、数字组成,然而不能以数字结尾,且Python辨别大小写。关键字就是具备非凡性能的标志符。 1.4.2 常量和变量常量就是不变的量。变量的次要作用是贮存信息,Python中变量名辨别大小写。 1.5 输出及输入函数输出函数:input()输入函数:print() 输出字符串 a = input("Please input a:")b = input("Please input b:")c = a + bprint(c)输出整数 a = int(input("Please input a:"))b = int(input("Please input b:"))c = a + bprint(c)一次输出两个字符串(字符串之间用空格隔开) ...

May 17, 2021 · 1 min · jiezi

关于django:1234

第一章 Python语言概述 1.1 计算机根底1.1.1 计算机特点运算速度快计算精确度高具备存储和罗逻辑判断能力 haode具备自动控制能力 1.1.2 计算机罕用设置及编码二进制数二进制数制与其余数制(1)十进制(十进位计数制)(2)八进制(八进位计数制)(3)十六进制(十六进位计数制)ASCII码Unicode编码和UTF-8编码进制转换 1.1.3 计算机系统组成 计算机硬件零碎(计算机五大部件):运算器、控制器、存储器、输出设施、输出设备。运算器又称逻辑运算单元(Arithmetic Logic Unit,ALU),次要性能是对二进制编码进行算术运算及根本逻辑运算。运算后果由控制器指挥送到内存储器。控制器基本功能是从内存储器中取指令和执行指令。存储器具备记忆性能,用来保存信息。存储器的存储容量为字节,每个字节都有本人的编号,称为“地址”。计算机解决数据时,一次能够运算的数据长度称为一个“字”,一个字能够是一个字节,也能够是多个字节,1个字节等于8位,64位电脑处理器解决数据时一次能解决的最大位数为64位,也就是8个字节。内存储器间接与CPU相连接,容量小,速度快;外存储器,硬盘、磁带、光盘等。输出设施:键盘鼠标等;输出设备:显示器,打印机等; 1.1.4 操作系统性能:过程治理、存储管理、设施治理和文件治理。 1.1.5 程序设计语言第一代:机器语言由二进制0、1代码形成 第二代:汇编语言 第三代:高级语言C、Python、Java等 第四代:非过程化语言两个典型利用:数据库查问和应用程序生成器 1.2 Python语言简介Python之父是Guido Van Rossum,Guido也爱追剧,最喜爱的一部剧是Monty Python and the Fling Circus,Python就命名于此。去年底耐不住退休生存的寂寞,退出了微软,重返工作岗位。Python是齐全面向对象的语言。函数、模块、数字、字符串都是对象。Python在执行时,首先将".py"文件中的源代码翻译成Python的byte code(字节码),而后再由Python虚拟机执行这些byte code。 1.3 Python IDLE 开发环境1.3.1 Python IDLE开发环境装置1,Windows操作系统装置[Python Windows下载地址](https://www.python.org/downlo...2,Mac 操作系统装置[Python Mac下载地址](https://www.python.org/downlo...3,UNIX/LINUX 操作系统装置[Python UNIX/LINUX下载地址](https://www.python.org/downlo... 1.3.2 运行Python程序print("Goodbay World!")1.4 标识符和变量1.4.1 标识符和关键字标志符是用户编程时所应用的名字。标识符由能够由字母、下划线、数字组成,然而不能以数字结尾,且Python辨别大小写。关键字就是具备非凡性能的标志符。 1.4.2 常量和变量常量就是不变的量。变量的次要作用是贮存信息,Python中变量名辨别大小写。 1.5 输出及输入函数输出函数:input()输入函数:print() 输出字符串 a = input("Please input a:")b = input("Please input b:")c = a + bprint(c)输出整数 a = int(input("Please input a:"))b = int(input("Please input b:"))c = a + bprint(c)一次输出两个字符串(字符串之间用空格隔开) ...

May 14, 2021 · 1 min · jiezi

关于django:基于djangooauthtoolkit的统一认证流程单点登录

基于django-oauth-toolkit的对立认证流程(单点登录)这篇文章次要用于django的单点登录认证,django是作为认证服务器而不是转第三方登录; 当然, 结尾的代码也能够用于第三方认证并且django作为申请认证在users/models.py 写入: from django.contrib.auth.models import AbstractUserclass User(AbstractUser): passsettings中 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'users',]AUTH_USER_MODEL='users.User'pip install django-oauth-toolkitsettings中 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'users', 'oauth2_provider',]这里如果遇到django-oauth-toolkit装置有问题,能够升高版本装置, 个别1.2版本没什么问题 这里提供一下pip装置的版本作为参考 Django 3.2.2django-oauth-toolkit 1.2.0 python manage.py makemigrationspython manage.py migrateurls.py中 from django.contrib import adminfrom django.urls import include, pathurlpatterns = [ path('admin/', admin.site.urls), path('auth/', include('oauth2_provider.urls', namespace='oauth2_provider')),]settings中 LOGIN_URL='/admin/login/'创立超级管理员 python manage.py createsuperuserUsername: wiliamEmail address: me@wiliam.devPassword:Password (again):Superuser created successfully.执行django python manage.py runserver关上网址注册须要单点登录的利用 ...

May 8, 2021 · 1 min · jiezi

关于python3.x:django权限认证

Django权限认证零碎Django内置了弱小的用户认证auth模块,零碎默认应用auth_user表来存储用户数据。通过from django.contrib import auth能够导入auth模块,auth模块提供了许多函数用于认证内置办法authenticate(username='username',password='password'):提供了用户认证性能,即验证用户名以及明码是否正确,参数为username 和password;如果认证胜利(用户名和明码正确无效),便会返回一个User对象。login(Http Request, user):实现用户登录的性能,参数为HttpRequest对象和一个通过认证的User对象。如果未登录,request.user失去的是一个匿名用户对象Anonymous User对象。is_authenticated():判断以后申请是否通过了认证。logout(request):革除以后申请的全副session。create_user():创立新用户,至多提供用户名和用户明码,形如 user =User.objects.create_user(username='Tom',password='test',email='tom@163.com')。set_password(password):批改明码,形如user_obj.set_password('test')。check_password(password):查看明码是否正确,形如user_obj.check_password('test')。另外还有一个login_required装璜器,通过该装璜器可能使视图函数首先判断用户是否登录。如果未登录,网页会跳转到settings.py设置的LOGIN_URL参数对应的URLfrom django.contrib.auth.decorators import login_required@login_requireddef index(request):创立自定义权限的办法通过定义数据模型减少权限,在定义模型时,能够在Meta中定义权限在执行python manage.py makemigrations和python manage.py migrate命令后,就会减少一条权限,权限的名字个别是APP_name.Permission_name的模式。假如咱们在一个叫myapp的应用程序中建设以上数据模型,那么产生的权限名字就是myapp.add_testclass test(models.Model): name = models.CharField(max_length=32) class Meta: permissions = [('add_test','在test表中减少记录的权限')]通过代码减少权限,权限是django.contrib.auth.Permission的实例对象,可了解为权限记录保留在Permission表中,它蕴含name、codename、content_type 3个字段,其中的content_type与数据模型相关联,能够了解为content_type示意一个权限在哪个应用程序中的哪个数据模型中定义# views.pyfrom django.http import HttpResponsefrom . import modelsfrom django.contrib.auth.models import Permission,ContentType# 在此处编写视图函数代码def add_permission(request): content_type=ContentType.objects.get_for_model(models.test) # 生成一条权限记录并保留在Permission表中 permission=Permission.objects.create(codename='add_test',name='在test表中减少记录的权限',content_type=content_type) return HttpResponse('ok')案例阐明案例利用为au目录构造 au├─__init__.py├─admin.py├─apps.py├─models.py├─tests.py├─urls.py├─views.py├─migrations| ├─0001_initial.py| ├─__init__.py| ├─__pycache__| | ├─0001_initial.cpython-37.pyc| | └__init__.cpython-37.pycviews.py # /au/views.pyfrom django.contrib.auth import authenticate, loginfrom django.http import HttpResponse, JsonResponsefrom django.views.decorators.csrf import csrf_exemptimport json# 退出csrf认证避免跨域报错@csrf_exemptdef user_login(request): # 判断传输方式是否为get,登录传输表单须要post if request.method == 'GET': return HttpResponse('跳转test_auth/login') else: # 将post的body解析出username与password body = json.loads(request.body) username = body['username'] password = body['password'] # 通过解析传输过去的用户名与明码对用户认证 user_obj = authenticate(username=username, password=password) if user_obj: # 让用户处于登录状态 login(request, user_obj) return HttpResponse('跳转主页') else: return HttpResponse('跳转login')models.py ...

April 16, 2021 · 2 min · jiezi

关于python3.x:django使用csrf防止跨域报错

下载依赖pip install django-cors-headers注册利用INSTALLED_APPS = [ ... 'corsheaders' , ... ]增加中间件CorsMiddleware应放在尽可能高的,特地是能够产生如Django的回应任何中间件之前CommonMiddleware或白噪声的WhiteNoiseMiddleware。MIDDLEWARE = [ ... 'corsheaders.middleware.CorsMiddleware' , # 上面这句是默认的第一句 'django.middleware.common.CommonMiddleware' , ... ]为视图增加注解from django.views.decorators.csrf import csrf_exempt@csrf_exemptdef user_login(request): ...额定的设置# settings.py# 跨域django-cors-headers配置CORS_ALLOW_CREDENTIALS = TrueCORS_ORIGIN_ALLOW_ALL = True# 受权进行跨站点HTTP申请的起源列表CORS_ALLOW_ORIGINS = [ '*']# 理论申请所容许的HTTP动词列表。默认为CORS_ALLOW_METHODS = [ 'DELETE' , 'GET' , 'OPTIONS' , 'PATCH' , 'POST' , 'PUT' ,]# 收回理论申请时能够应用的非标准HTTP标头的列表。默认为:CORS_ALLOW_HEADERS = [ 'accept' , 'accept-encoding' , 'authorization' , 'content-type' , 'dnt' , 'origin' , 'user-agent' , 'x-csrftoken' , 'x-requested-with' ,]更多配置信息 ...

April 16, 2021 · 1 min · jiezi

关于django:django项目相关配置方法

orm查问对象序列化在最高层面,你能够像这样序列化数据:from django.core import serializersdata = serializers.serialize("xml", SomeModel.objects.all())serialize 函数的参数是数据序列化的指标格局 (查看 序列化格局)和用来序列化的 QuerySet。(实际上,第二个参数能够是任何生成 Django 模型实例的迭代器,但它简直总是一个QuerySet)。django.core.serializers.get_serializer(format)XMLSerializer = serializers.get_serializer("xml")xml_serializer = XMLSerializer()xml_serializer.serialize(queryset)data = xml_serializer.getvalue()利用Django的serialize序列化成json对象 import jsonfrom django.core.serializers import serializejson_data = serialize('json', goods) # strjson_data = json.loads(json_data) # 序列化成json对象建设超级用户python manage.py createsuperuser创立我的项目django-admin startproject 我的项目名创立利用python manage.py startapp 利用名model函数逆向生成mysql配置pymysql# project我的项目文件夹下的__init__.pyimport pymysqlpymysql.install_as_MySQLdb()配置数据库连贯信息# project我的项目文件夹下的settings.pyDATABASES = { 'default': {'ENGINE': 'django.db.backends.mysql', # 数据库引擎,指明数据库类型 'HOST': '127.0.0.1', # 数据库装置在本机 'PORT': '3306', # 端口号 'NAME': 'test_orm', # 数据库名称 'USER': 'root', # 数据库用户名 'PASSWORD': 'root', # 数据库明码 }}将利用增加到启动项里INSTALLED_APPS = [ '利用名称']在利用model层写入函数# 例如from django.db import modelsclass author(models.Model): name = models.CharField(max_length=10, verbose_name='姓名') email = models.EmailField(verbose_name='邮箱') birthday = models.DateField(verbose_name='生日') header = models.ImageField(verbose_name='头像')逆向生成mysql在terminal运行 ...

April 15, 2021 · 2 min · jiezi

关于python3.x:django-orm使用

ORM(Object Relational Mapping)orm应用步骤在我的项目应用的数据库管理系统中建设数据库。DATABASES = { 'default': {'ENGINE': 'django.db.backends.mysql', # 数据库引擎,指明数据库类型 'HOST': '127.0.0.1', # 数据库装置在本机 'PORT': '3306', # 端口号 'NAME': 'test_orm', # 数据库名称 'USER': 'root', # 数据库用户名 'PASSWORD': 'root', # 数据库明码 }}在我的项目的配置文件settings.py中设置数据库的连贯字符。INSTALLED_APPS = [ '利用名称']在应用程序的models.py文件中编写继承于models.Model的数据模型。运行python manage.py makemigrations、python manage.py migrate两个命令生成数据库表。应用Django ORM操作数据库表。# 在project文件夹下的_init_中须要应用pymysql替换mysqlimport pymysqlpymysql.install_as_MySQLdb()罕用orm字段类型Char Field:字符类型,必须提供max_length参数,max_length示意字符长度。verbose_name在Django Admin治理后盾是字段的显示名称,可了解为字段别名,verbose_name在SQL层面没有具体的体现,也就是说加不加verbose_name对数据库中的字段没影响。name=models.CharField(max_length=32,verbose_name='姓名')Email Field:邮箱类型,实际上是字符类型,只是提供了邮箱格局测验。email=models.EmailField(verbose_name='邮箱')Text Field:文本类型,存储大段文本字符串。字符串如果超过 254 个字符倡议应用Text Field。descript=models.TextField(verbose_name="简介")Integer Field:整数类型。int= models.IntegerField()Date Field:日期字段。date=models.DateField(auto_now=True, auto_now_add=False)auto_now参数主动保留以后工夫,个别用来示意最初批改工夫。在第一次创立记录的时候, Django将auto_now_add字段值主动设置为以后工夫,用来示意记录对象的创立工夫Time Field:工夫字段。time= models.TimeField(auto_now=False, auto_now_add=False)Date Time Field:日期工夫字段,合并了日期字段与工夫字段。datetime=models.DateTimeField(auto_now=False, auto_now_add=False)File Field:实际上是字符串类型,用来把上传的文件的门路保留在数据库中。文件上传到指定目录,主要参数upload_to指明上传文件的保留门路,这个门路与Django配置文件的MEDIA_ROOT变量值无关。filetest =models.FielField (upload_to = 'test/')Image Field:实际上是字符串类型,用来把上传的图片的门路保留在数据库中。图片文件上传到指定目录,主要参数upload_to指明上传图片文件的保留门路,与File Field中upload_to雷同。picture = models.Image Field(upload_to = 'pic/')常用字段属性db_index:db_index=True示意设置此字段为数据库表的索引。title = models.CharField(max_length=32, db_index=True)unique:unique=True示意该字段在数据库表中不能有反复值。default:设置字段默认值,如default='good'。auto_now_add:Datetime Field、Date Field、Time Field 这 3 种字段的独用属性, auto_now_add=True示意把新建该记录的工夫保留为该字段的值。auto_now:Datetime Field、Date Field、Time Field这3种字段的独用属性,auto_now= True示意每次批改记录时,把以后工夫存储到该字段。基本操作CRUD增形式一new_emp=models.employee.objects.create(name="tom",email="tom@163.com",dep_id=66)形式二:应用save办法new_emp= models.employee (name="tom",email="tom@163.com",dep_id=66)new_emp.save()删删除记录,用filter()过滤出符合条件的记录后调用delete()删除。models.employee.objects.filter(name= "张三").delete()改# 将指定条件的记录更新,并更新指定字段的值models.employee.objects.filter(name='tom').update(email="tom2@163.com")# 批改单条数据# 取出单条信息obj = models.employee.objects.get(id=66)# 批改obj.email = "tom2@sina.com"# 保留批改obj.save()查# 获取全副Emp_list= models.employee.objects.all()# 获取单条数据,数据不存在则报错Emp=models.employee.objects.get(id=123)# 获取指定条件的记录集Emp_group=models. employee.objects.filter(name= "张三")Django ORM数据操作罕用函数Django的Query Set对象集实质上是对应于数据库表的记录汇合,QuerySet有一个个性就是“惰性”,即返回值为Query Set的函数不会立刻去数据库操作数据。当咱们用到Query Set的值时,它才会去数据库中获取数据,如遍历QuerySet、打印Query Set、判断Query Set是否有值时,它才会到数据库表中获取数据。all()函数,返回符合条件的全副记录。objects = models.employee.objects.all()filter()函数,返回指定条件的记录。filter前面的括号内为过滤条件,相似于SQL中语句where前面的条件语句。objects = models.employee.objects.filter(name='tom')filter前面的括号内寄存的是过滤条件,针对数据表的字段过滤个别用“字段名+双下划线+条件名词”,括号内的过滤条件能够有多个,这些条件之间是“与”关系也就是and关系,条件名词在Django ORM中次要包含contains、icontains、in、gt、lt、range、startswith、endswith、istartswith、iendswith等,局部用法如下。# 获取name字段蕴含“Tom”的记录models.employee.objects.filter(name__contains="Tom")# 获取name字段蕴含“tom”的记录,icontains疏忽大小写models.employee.objects.filter(name__icontains="tom")# 获取employee数据表中id等于10、20、66的数据models.employee.objects.filter(id__in=[10, 20, 66])# 获取employee数据表中id不等于10、20、66的记录,因为后面用的是excludemodels.employee.objects.exclude(id__in=[10, 20, 66])。# 获取employee数据表中id大于1 且 小于10的记录,两个过滤条件的关系等价于SQL的andmodels.employee.objects.filter(id__gt=1, id__lt=10)# 获取employee数据表中id在范畴1~66内的记录,等价于SQL的id bettwen 1and 66models.employee.objects.filter(id__range=[1, 66])# 获取employee数据表中birthday字段中月份为9月的记录,birthday为日期格局models.employee.objects.filter(birthday__month=9)exclude()函数,返回不合乎括号内条件的记录,与filter()函数具备相同的意义。objects = models.employee.objects.exclude(name='tom')order_by()函数,依照order_by前面括号中的字段排序。objects = models.employee.objects.exclude(name='tom').order_by('name','id')字段名中加“-”,示意按该字段倒序排列。如下代码示意,按name字段倒序排列列表。objects = models.employee.objects.order_by('-name')distinct()函数,去掉记录汇合中齐全一样的记录(重复记录),而后返回这个记录集。objects = models.employee.objects.filter (name='tom').distinct()返回QuerySet以下3个函数返回其余数据类型,能够了解为非凡的Query Set类型。values()函数,返回一个字典类型序列。objects = models.employee.objects.values('id','name','email')print( objects)输入如下<Query Set[{'id': 1, 'name': '刘大华', 'email': 'ldh@163.com'}, {'id': 2, 'name': '古连田', 'email': 'glt@123.com'}, {'id': 4, 'name': '张三', 'email': 'zs@sina.com'}]>values_list()函数,返回一个元组类型序列。objects = models.employee.objects.values_list('id','name','email')print( objects)输入如下<Query Set[(1, '刘大华', 'ldh@163.com'), (2, '古连田', 'glt@123.com'), (4, '张三','zs@sina.com')]>get()、first()、last()返回单个对象,能够了解为返回数据表中的一条记录。# 返回id为1的记录,括号内是过滤条件object1 = models.employee.objects.get(id=1)# 返回数据集的第一条记录object2 = models.employee.objects.first()# 返回数据集的最初一条记录object3 = models.employee.objects.last()# 返回数据集的个数object4= models.employee.objects.count()跨表操作Django中的数据模型关联关系次要是由外键、多对多键、一对一键造成的关联关系,Django数据模型的实例对象中保留着关联关系相干的信息,这样在跨表操作过程中,咱们能够依据一个表的记录的信息查问另一个表中相关联的记录,充分利用关系型数据库的特点。Foreign Key字段在数据模型中个别把Foreign Key字段设置在“一对多”中“多”的一方,Foreign Key能够和其余表做关联关系,也能够和本身做关联关系。Foreign Key字段个别在models.py文件的数据模型类中定义,其模式如下。# 员工的部门,外键,造成一对多的关系dep=models.ForeignKey(to="department",to_field="id",related_name="dep_related",on_delete=models.CASCADE)Foreign Key字段次要有4个属性,如下。 ...

April 15, 2021 · 3 min · jiezi

关于django:Django中的View操作

导入:from django.views import View一、查问所有数据查问数据在自定义的视图类中定义get办法应用django.http模块中的JsonResponse对非json格局的数据做返回解决在JsonResponse必须增加safe=False参数,否则会报错:In order to allow non-dict objects to be serialized set the safe parameter to False.from django.http import HttpResponse from django import http # Create your views here. class UserView(View): ''' 用户视图 ''' def get(self, request): # 模型类实例化对象 users = UserProfile.objects.all() user_list = [] for user in users: user_dict = { 'id': user.id, 'username': user.username, 'password': user.password, 'open_id': user.open_id, 'code': user.code } user_list.append(user_dict) return http.JsonResponse(user_list) 二、创立数据应用django中的json,把前端传递过去的json数据转成字典应用django.db.models模块中的Q来查问多个字段在数据库中是否存在from django.views import View from django.http import HttpResponse from django import http from django.db.models import Q import json class UserView(View): ''' 用户视图 ''' def post(self, request): # 获取数据, json转字典 dict_data = json.loads(request.body.decode()) print(dict_data) nick_name = dict_data.get('nickName') code = dict_data.get('code') open_id = "xljsafwjeilnvaiwogjirgnlg" # 校验数据 result = UserProfile.objects.filter(Q(code=code) | Q(open_id=open_id)) if not result.exists(): # 数据入库 user = UserProfile.objects.create( username=nick_name, open_id=open_id, code=code ) # 返回响应 user_dict = { 'id': user.id, 'username': user.username, 'password': user.password, 'open_id': user.open_id, 'code': user.code } return http.JsonResponse(user_dict) return http.JsonResponse("用户已存在", safe=False, status=202)三、查问某一条数据(单个)前端须要传递pk/id值,通过pk/id查问数据,查问一条数据必须用get,不能用filter,否则会报错:AttributeError: 'QuerySet' object has no attribute 'id'数据转换返回响应class UserProfileDetail(View): ''' 详情视图 ''' def get(self, request): userInfo = UserProfile.objects.get(id=id) if not userInfo: return HttpResponse("查问的用Info户不存在", status=404) user_dict = { 'id': userInfo.id, 'username': userInfo.username, 'password': userInfo.password, 'open_id': userInfo.open_id, 'code': userInfo.code } return http.JsonResponse(user_dict, status=200) 四、更新一条数据前端须要传递pk/id值,通过pk/id查问数据,查问一条数据必须用get,不能用filter,否则会报错:AttributeError: 'QuerySet' object has no attribute 'id'更新一条数据时必须应用filter来查问数据集,再应用update(**data)来更新数据,不能应用get,否则会报错:AttributeError: '模型类' object has no attribute 'update'get查问获取到的是数据对象,而filter查问获取到的是数据集class UserProfileDetail(View): ''' 详情视图 ''' def put(self, request, id): data_dict = json.loads(request.body.decode()) userInfo = UserProfile.objects.get(id=id) if not userInfo: return HttpResponse("查问的用Info户不存在", status=404) UserProfile.objects.filter(id=id).update(**data_dict) userInfo = UserProfile.objects.get(id=id) user_dict = { 'id': userInfo.id, 'username': userInfo.username, 'password': userInfo.password, 'open_id': userInfo.open_id, 'code': userInfo.code } return http.JsonResponse(user_dict, status=200)五、删除某一条数据class UserProfileDetail(View): ''' 详情视图 ''' def delete(self, request, id): userInfo = UserProfile.objects.filter(id=id) if not userInfo: return HttpResponse("删除的数据不存在", status=404) UserProfile.objects.filter(id=id).delete() return HttpResponse("数据删除胜利", status=204)上述的操作只能实用于数据表中字段很少的状况,如果字段较多,写起来会很麻烦,不利于开发

March 16, 2021 · 2 min · jiezi

关于django:五Django-Web开发cookie与session

一.cookie1.1 什么是cookie?cookie是由服务器生成,存储在浏览器端的一小段文本信息。cookie的特点:1)以键值对形式进行存储。2)通过浏览器拜访一个网站时,会将浏览器存储的跟网站相干的所有cookie信息发送给该网站的服务器。3)cookie是基于域名平安的。4)cookie是有过期工夫的,如果不指定,默认敞开浏览器之后cookie就会过期。1.2 cookie的作用HTTP协定是无状态的,每次申请都是独立的,它的执行状况和后果与后面的申请和之后的申请没有任何的关系,而cookie就是为了满足人们对http申请状态的需要而诞生的。1.3 Django中cookie的应用设置cookie示例 def cookie_set(request): response = HttpResponse("<h1>设置Cookie</h1>") response.set_cookie('your_cookie', '你好') return response罕用: rep.set_cookie(key,value,...)rep.set_signed_cookie(key,value,salt='加密字符串', max_age=None, ...)获取cookie示例: def cookie_get(request): if 'your_cookie' in request.COOKIES: response = HttpResponse("获取Cookie") return response罕用: request.COOKIES['key']request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)总结办法形容rep.set_cookie(key,value,...)设置cookierep.set_signed_cookie(key,value,salt='加密字符串', max_age=None, ...)加盐的cookie设置,参数:1)key, 键2)value='', 值 3) max_age=None, 超时工夫 4) expires=None, 超时工夫(IE requires expires, so set it if hasn't been already.) 5) path='/', Cookie失效的门路,/ 示意根门路,非凡的:根门路的cookie能够被任何url的页面拜访 6) domain=None, Cookie失效的域名 7) secure=False, https传输 9) httponly=False 只能http协定传输,无奈被JavaScript获取(不是相对,底层抓包能够获取到也能够被笼罩)request.COOKIES['key']一般cookie获取request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)加盐的cookie获取,参数:1) default: 默认值 2) salt: 加密盐 3) max_age: 后盾管制过期工夫二.session对于敏感、重要的信息,倡议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息,这时候就要用到session。session将重要信息保留在服务器端,返回给客户端一个随机字符串,保留在cookie中。 ...

March 12, 2021 · 1 min · jiezi

关于django:四Django-model-操作

model操作model罕用操作对应的就是数据库中的增删改查参照文档https://docs.djangoproject.co...示例文件 from django.db import modelsclass Students(models.Model): """学生表""" username = models.CharField(max_length=64, null=False, unique=True) age = models.IntegerField() cls = models.ForeignKey('ClassInfo', on_delete=models.DO_NOTHING)class ClassInfo(models.Model): """班级表""" title = models.CharField(max_length=64, null=False, unique=True) teachers = models.models.ManyToManyField("Teachers")class Teachers(models.Model): """老师表""" name = models.CharField(max_length=16, null=False, unique=True)1.单表操作1.1减少数据第一种形式obj = models.Students(username='张三', cls_id='1')obj.save()第二种形式models.Students.objects.create(username='张三', cls_id='1)1.2查问数据get获取# 获取id为1的学生models.Students.objects.get(id='1')filter获取# 查问id=1的学生obj = models.Students.objects.filter(id='1')# 查问年龄大于19的学生obj = models.Students.objects.filter(age__gt=19)# 查问年龄大于19小于22的学生obj = models.Students.objects.filter(age__gt=19, age__lt=22)# 查问id在[1, 3, 5, 6]的学生obj = models.Students.objects.filter(id__in=[1, 3, 5, 6])# 查问名字蕴含“伟”的学生obj = models.Students.objects.filter(username__contains=='伟')all()查问所有stu_list = models.Students.objects.all() # 返回查问集,外面都是对象vlauesstu_list = models.Students.objects.values() # 返回查问机,外面都是字典,不写字段,默认显示错有vlaues_liststu_list = models.Students.objects.values_list() # 返回查问机,外面都是元组1.3批改数据update# 批改id为1的学生的班级obj = models.Students.objects.filter(id='1') # 通过查问找到id为1的学生obj.update(cls_id=2) # 应用update更新该学生信息1.4删除数据# 批改id为1的学生的班级obj = models.Students.objects.filter(id='1') # 通过查问找到id为1的学生obj.delete() # 应用delete() 删除1.5查问集查问函数 ...

March 12, 2021 · 1 min · jiezi

关于django:三Django-Web开发之ORM

Django中的ORM对象关系映射(Object Relational Mapping,简称ORM)是通过应用形容对象和数据库之间映射的元数据,将面向对象语言程序中的对象主动长久化到关系数据库中。 参考文档:https://docs.djangoproject.co...Django数据库配置# settings文件下DATABASES = { "default": { "ENGINE": "django.db.backends.mysql", # 这里能够依据理论状况批改,譬如换成oracle、PostgreSQL等 "NAME": "数据库名称", "USER": "用户名", "PASSWORD": "明码", "HOST": "数据库拜访地址", "POST": 3306 # Mysql数据库默认应用3306 }}建设modelmodel蕴含了存储的数据的重要字段和行为。一个模型映射到一个数据库表。model示例from django.db import modelsclass Students(models.Model): name = models.CharField(max_length=30) # CharField为字段类型,max_length 为字段参数选项 age = models.IntegerField() gender = models.BooleanField() cs = models.ForeignKey('ClassInfo', on_delete=models.DO_NOTHING)class ClassInfo(modes.Modell): title = models.CharField(max_length=30)执行,生成数据表 python manage.py makemigrationspython manage.py migrate常用字段类型形容AutoField主动增长的IntegerField,通常不必指定,不指定时Django会主动创立属性名为id的主动增长属性。BooleanField布尔字段,值为True或False。NullBooleanField反对Null、True、False三种值。CharField(max_length=最大长度)字符串。参数max_length示意最大字符个数。TextField大文本字段,个别超过4000个字符时应用。IntegerField整数DecimalField(max_digits=None, decimal_places=None)十进制浮点数。参数max_digits示意总位。参数decimal_places示意小数位数。FloatField浮点数。参数同上DateField:([auto_now=False, auto_now_add=False])日期。1)参数auto_now示意每次保留对象时,主动设置该字段为以后工夫,用于"最初一次批改"的工夫戳,它总是应用以后日期,默认为false。2) 参数auto_now_add示意当对象第一次被创立时主动设置以后工夫,用于创立的工夫戳,它总是应用以后日期,默认为false。3)参数auto_now_add和auto_now是互相排挤的,组合将会产生谬误。TimeField工夫,参数同DateField。DateTimeField日期工夫,参数同DateField。FileField上传文件字段。ImageField继承于FileField,对上传的内容进行校验,确保是无效的图片。字段选型罕用选项选项名形容default默认值。设置默认值。primary_key若为True,则该字段会成为模型的主键字段,默认值是False,个别作为AutoField的选项应用。unique如果为True, 这个字段在表中必须有惟一值,默认值是False。db_index若值为True, 则在表中会为此字段创立索引,默认值是False。db_column字段的名称,如果未指定,则应用属性的名称。null如果为True,示意容许为空,默认值是False。blank如果为True,则该字段容许为空白,默认值是False。关系表选项ForeignKey 外键关联个别把ForeignKey字段设置在 '一对多'中'多'的一方。ForeignKey能够和其余表做关联关系,,也能够和本身做关联关系。选项名形容to设置要关联的表to_field设置要关联的表的字段related_name反向操作时,应用的字段名,用于代替原反向查问时的'表名_set'related_query_name反向查问操作时,应用的连贯前缀,用于替换表名on_delete当删除关联表中的数据时,以后表与其关联的行的行为。db_constraint是否在数据库中创立外键束缚,默认为True。on_delete 可选项选项名形容models.CASCADE删除关联数据,与之关联也删除models.DO_NOTHING删除关联数据,引发谬误IntegrityErrormodels.PROTECT:删除关联数据,引发谬误ProtectedErrormodels.SET_NULL:删除关联数据,与之关联的值设置为null(前提FK字段须要设置为可空)models.SET_DEFAULT:删除关联数据,与之关联的值设置为默认值(前提FK字段须要设置默认值)models.SET|删除关联数据,. 与之关联的值设置为指定值或者可执行对象的返回值,设置:models.SET(值) ManyToManyField多对多用于示意多对多的关联关系,在数据库中通过第三张表来建设关联关系。选项名形容to设置要关联的表related_name反向操作时,应用的字段名,用于代替原反向查问时的'表名_set'related_query_name反向查问操作时,应用的连贯前缀,用于替换表名symmetrical仅用于多对多自关联时,指定外部是否创立反向操作的字段。默认为True。through在应用ManyToManyField字段时,Django将主动生成一张表来治理多对多的关联关系,也反对手动创立第三张表,此时就须要通过through来指定第三张表的表名。through_fields设置关联的字段。db_table默认创立第三张表时,数据库中表的名称。DatetimeField、DateField、TimeField特有参数选项名形容auto_now_add 配置auto_now_add=True,创立数据记录的时候会把以后工夫增加到数据库。auto_now 配置上auto_now=True,每次更新数据记录的时候会更新该字段。

March 12, 2021 · 1 min · jiezi

关于django:一DjangoMVT以及Django基础

一.框架框架是应答某类软件设计问题而产生的,它是由各个软件模块组成的,每个模块都有特定的性能,模块与模块之间通过相互配合来实现软件的开发。二. MVC 框架MVC简介MVC的理念: 分工,让专门的人去做专门的事。MVC的核心思想: 解耦。Web MVC框架模块性能M:Model, 和数据库进行交互。V:View, 产生html页面。C:Controller, 用于接管、解决申请,与M和V进行交互,返回应答。如下图所示 三.Django框架3.1Django简介Django ,遵循MVC思维,然而有本人的一个名词,叫做MVT。3.2Django中的MVTM:Model,模型, 和MVC中M性能雷同,同样是和数据库进行交互。V:View,视图, 相当于MVC中C,接管、解决申请,与M和T进行交互,返回应答。T:Template,模板, 和MVC中V性能雷同。如下图所示 假设baidu为Django开发 3.3Django装置pip install django// 指定版本 装置pip install django==2.2.23.4第一个Django我的项目建设我的项目django-admin startproject mysite我的项目目录.├── manage.py // django我的项目的管理文件└── mysite ├── __init__.py //__init__.py: 阐明是一个python包。 ├── settings.py //配置文件 ├── urls.py //url路由配置 └── wsgi.py // web服务器和Django交互的接口创立Django利用(app)cd mysite //进入django我的项目中python manage.py startapp testapp // testapp 为App的名字// 也能够应用django-admin startapp testapp 3.5配置文件 settings注册利用INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',# 'testapp', 晚期版本应用 'testapp.apps.TestappConfig', # 2.0以上版本应用 ]配置时区和语言环境LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'配置templates 目录TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },]配置staticSTATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'),)数据库配置DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}3.6 视图在Django中,通过浏览器去申请一个页面时,应用视图函数来解决这个申请的,视图函数解决之后,要给浏览器返回页面内容。视图函数定义视图函数视图函数在views.py中定义。 ...

March 12, 2021 · 2 min · jiezi

关于django:Django32LTS版4月即将发布带你提前尝鲜

Django 3 版本系列的 LTS(长期反对版本)马上就要在 4 月份公布,这个版本将会陪伴咱们两年之久。在新版本公布前夕来提前理解下有哪些乏味的新性能,这些性能在公布时应该不会变动了。 装置一个 3.2 的 Django 版本截止到 3 月 9 日,已公布Django beta2版本。Django 3.2 仅反对 Python3.6、3.7、3.8 和 3.9,装置时留神 Python 版本。 1、创立虚拟环境 $ mkdir django3$ cd django3$ python3.6 -m venv venv$ source venv/bin/activate2、装置 django3.2 b1 (venv) $ pip install git+https://github.com/django/django@3.2b13、创立新的我的项目和 app ,避免你本地环境影响,这里间接应用虚拟环境中的命令来创立 (venv) $ venv/bin/django-admin startproject django3(venv) $ cd django3(venv) $ python manage.py startapp blog4、将 app 增加到 settings。 # settings.pyINSTALLED_APPS = [ # ... 'blog',]DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'django3', 'USER': 'root', 'PASSWORD': 'Root1024', 'HOST': '127.0.0.1', 'PORT': '3306', }}5、创立 model 用来测试: ...

March 11, 2021 · 3 min · jiezi

关于django:日志分割解决方案

线上降级后,发现日志不再宰割,记录以下排查过程以及所波及的常识。 1.配置文件排查询问老工程师,反馈是通过Python的logging模块进行宰割的,其中logging模块介绍如下:logging模块采纳模块化设计思维,次要包含四种模块: Logger:记录器,提供应用程序调用的各种接口;Handler:处理器,解决记录器产生的日志;Filter:过滤器,提供更好的粒度管制;Formatters:格局器,格式化日志内容的组成和音讯字段;其中logging模块详解请见:logging模块详解(转自刘江的博客)日志解决流程如下图所示: Django中的logging配置解释如下,其中Django读取settings.py中的LOGGING配置: LOGGING = { 'version': 1, #版本号 'disable_existing_loggers': False, 'formatters': { # 格局器 'verbose': { # 简单格局名称 'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}', 'style': '{', }, 'simple': { # 简洁格局名称 'format': '{levelname} {message}', 'style': '{', }, }, 'filters': { # 过滤器 'special': { # 过滤器名称 '()': 'project.logging.SpecialFilter', 'foo': 'bar', }, 'require_debug_true': { '()': 'django.utils.log.RequireDebugTrue', }, }, 'handlers': { # 处理器 'logit': { # 名称 'level': 'DEBUG', 'class': 'logging.handlers.TimedRotatingFileHandler',# 按某一时间来宰割 'filename': '/tmp/logit.log', # 门路 'when': 'midnight', # Roll over at midnight 'backupCount': 10, # 备份数量 'formatter': 'verbose', # 格局器 }, 'console': { # 处理器名称 'level': 'INFO', # 级别 'filters': ['require_debug_true'], # 过滤器 'class': 'logging.StreamHandler', # 流处理器 'formatter': 'simple' # 格局器 }, 'file': { 'level': 'DEBUG', 'class': 'logging.FileHandler', # 文件处理器 'filename': '/path/to/django/debug.log', # 文件门路 }, 'mail_admins': { # 名称 'level': 'ERROR', 'class': 'django.utils.log.AdminEmailHandler', # 邮件处理器 'filters': ['special'] } }, 'loggers': { 'django': { 'handlers': ['console'], 'propagate': True, }, 'django.request': { 'handlers': ['mail_admins'], 'level': 'ERROR', 'propagate': False, }, 'myproject.custom': { 'handlers': ['console', 'mail_admins'], 'level': 'INFO', 'filters': ['special'] } }}然而排查线上配置文件,并未配置TimedRotatingFileHandler处理器。并且查看文件批改记录及git记录,该文件并未批改。所以判断,日志宰割应用了其余办法。 ...

March 7, 2021 · 2 min · jiezi

关于django:01安装GrapheneDjango系统学

前言: 有能力能够本人看官网文档. 装置环境要求Django版本大于1.11 装置办法pip 装置pip install graphene-django软件退出DjangoDjango我的项目的settings.py的INSTALLED\_APPS中退出Graphene-Django, 另外要退出动态资源,用于GraphiQL 补充一点: GraphiQL是GraphQL的集成开发环境(IDE),多了一个i就是integrated(集成,交融)的意思。 INSTALLED_APPS = [ ... "django.contrib.staticfiles", # GraphiQL须要这个动态资源 "graphene_django"]退出路由Django我的项目的urls.py退出视图,Django版本不同,用法稍有不同。看起来仿佛就是一个正则的区别。 Django 2.0及以上版本 from django.urls import pathfrom graphene_django.views import GraphQLViewurlpatterns = [ # ... path("graphql", GraphQLView.as_view(graphiql=True)),]Django 1.11版本: from django.conf.urls import urlfrom graphene_django.views import GraphQLViewurlpatterns = [ # ... url(r"graphql", GraphQLView.as_view(graphiql=True)),]补充一点,如果你不心愿在浏览器中应用GraphiQL,视图里将graphiql的True改为False。 定义计划定义一个计划(schema),我了解schema为计划。在计划里,你能够指定如何查问(query)和变动(mutate)。我写一个实例: import grapheneclass Query(graphene.ObjectType): hello = graphene.String(default_value="Hi!")schema = graphene.Schema(query=Query)大略的思路就是: 继承graphene.ObjectType, 定义好你要查问的字段以及数据起源, 最初将定义的查问对象赋值给Schema的query里. 配置计划计划定义好了, 还须要把计划给到django的配置里, 也就是我的项目的settings.py 大略长这样: GRAPHENE = { "SCHEMA": "django_root.schema.schema"}番外: CSRF爱护在路由urls.py里, 加一层csrf\_exempt即可. ...

February 26, 2021 · 1 min · jiezi

关于django:Django314中文文档1快速开始part1

写在后面该系列为读者首次翻译Django相干技术文档,次要作为学习查阅之用,如有谬误,请斧正,还望海涵! getting started第一次应用Django?第一次进行web开发?你来到了正确的中央!立即开始浏览这一章节并开始运行吧! Django概述Django是在快节奏的新闻编辑室环境下所开发的,旨在疾速便捷地进行web开发,本文档的目标是通过一些技术细节去理解Django是如何工作的,让咱们立刻开始吧! 编写您的第一个Django app,part 1让咱们通过示例进行学习。通过本示例的学习,咱们将疏导你实现一个根本的民意调查利用app的创立工作,它将包含以下两局部。 一个能够查看民心并且进行投票的公共站点一个容许您增加、扭转、删除民心的治理站点咱们必须向您再次确认Django installed曾经实现。您能够通过以下命令来确认Django是否装置以及版本。 python -m django --version如果Django曾经装置,那么您将能够看到版本信息,如果未装置,将会产生谬误"No module named django"。本次教程撰写是基于Django3.1,反对python3.6及更高版本,如果Django版本不合乎,您能够查看对应版本的Django教程,或者更新Django到最新版本。如果您仍在应用较老版本的python,请确认应用相适应的Django版本。 Django versionPython versions1.112.7,3.4,3.5,3.6,3.7(added in 1.11.17)2.03.4,3.5,3.6,3.72.13.5,3.6,3.72.23.5,3.6,3.7,3.8(added in 2.2.8),3.9(added in 2.2.17)3.03.6,3.7,3.8,3.9(added in 3.0.11)3.13.6,3.7,3.8,3.9(added in 3.1.3)创立我的项目如果这是您第一次应用Django,您将必须进行一些初始化操作,也就是说您须要主动生成一些代码来搭建Django工程,包含数据库的配置,Django选项配置以及应用程序配置。关上命令行工具,cd到您心愿存储代码的文件夹下,输出以下命令并运行 django-admin startproject mysite #创立我的项目mysite这将在以后文件夹下创立一个mysite文件夹。留神:请防止应用python内置关键词以及django常用词! 代码应该放在何处?如果您的后端采纳老版的PHP(不应用任何古代框架),您很有可能将代码搁置于web服务器文件夹门路下(比方 /var/www)。在Django框架内并不这样做。因为这样做会产生一些危险,其他人可能通过网络查看您的代码,不利于平安。 startproject命令创立文件夹如下 mysite/ manage.py mysite/ __init__.py settings.py urls.py asgi.py wsgi.py这些文件作用如下: 内部的mysite文件夹是整个我的项目的容器,它的命名不影响Django的运行,因而您凭借爱好任意批改它manage.py:一个命令行实用程序,能够让您通过各种形式与此Django我的项目进行交互。外部的mysite文件夹是一个该我的项目须要应用的Python扩大包,在您须要引入文件夹内的任何文件时须要应用到它的命名(比方mysite.urls)。mysite/__init__.py:空文件,旨在通知python解释器,该文件夹应被解释为一个python扩大包。mysite/setting.py:此Django我的项目的配置文件。mysite/urls.py:此Django我的项目的Urls门路文件,用于定义url。mysite/asgi.py:为您的Django我的项目提供兼容ASGI的服务器的入口。mysite/wsgi.py:为您的Django我的项目提供兼容WSGI的服务器的入口。开发服务器确认您的Django我的项目能够失常运行。cd到mysite文件夹内并运行以下命令 python manage.py runserver您将看到在命令行内看到以下输入 Performing system checks...System check identified no issues (0 silenced).You have unapplied migrations; your app may not work properly until they are applied.Run 'python manage.py migrate' to apply them.January 22, 2021 - 15:50:53Django version 3.1, using settings 'mysite.settings' Starting development server at http://127.0.0.1:8000/ Quit the server with CONTROL-C. ...

February 10, 2021 · 1 min · jiezi

关于django:irisDjango模板引擎的语法格式和语法标签使用方法include标签传递变量方法

根底配置篇:博客模板的格局语法和后端如何传递数据到模板逻辑后面的章节中,咱们抉择了应用iris.Django作为咱们前端应用的模板引擎,因而咱们这里只介绍它的相干语法。 在网络上,对于Django模板的标签和语法教程少之又少,并且很多都是不全面的,要么就是抄来抄去的无用文章,要么就是简略寥寥几个标签,很多时候,都不能满足应用。比方include引入模板后,如何传递变量、如何在页面申明一个长期变量等问题。为了解决网络上短少介绍内容的问题,我特意翻读了iris.Django的源码,并将大部分罕用到的标签,都整理出来,供参考和应用。 iris.Django模板语法和应用iris.Django模板引擎的模板解析器是pongo2,它是一个相似于 Django 模板语法的模板引擎。Django 是一个凋谢源代码Python编写的Web利用框架。它的模板引擎语法绝对简略,清晰,应用起来也十分不便。因而咱们就应用它做为咱们的博客的前端模板引擎了。 模板的嵌套援用 include往往制作模板的时候,咱们会将一些公共局部,比方header、footer、aside等局部,抽离进去独立寄存,不须要在每一个页面都反复编写,只须要在每一个页面引入它们即可。这个时候,咱们能够应用include标签。 {% include "partial/header.html" %}{% include "partial/footer.html" %}include能够将一个拆分进去的代码片段(fragment)嵌入到残缺的文档中。应用模式是{% include "模板文件" %}。 如果须要引入的模板不存在的话,它会报错,如我咱们不晓得引入的模板是否存在,则须要减少if_exists判断。 {% include "partial/header.html" if_exists %}这样如果header.html模板存在的话,则会引入,即便不存在,也不会报错,只是被疏忽掉了。 默认状况下,include引入的模板,它会继承以后模板的所有变量,如果想给include引入的模板减少另外的变量,能够应用with来减少。如: {% include "partial/header.html" with title="这是申明给header应用的title" %}这样就给include引入的模板定义了title变量,以后模板的其余变量它同样也能够持续应用了。 如果须要申明多个变量给include引入的模板应用,能够间断应用key=value的模式减少,它们之间应用空格隔开,如: {% include "partial/header.html" with title="这是申明给header应用的title" keywords="这是申明给header应用的keywords" %}如果只想让include引入的模板应用指定的几个变量,而不是以后模板的所有变量,能够应用only来做限度: {% include "partial/header.html" with title="这是申明给header应用的title" keywords="这是申明给header应用的keywords" only %}而后在header.html中应用: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>{{title}}</title> <meta name="keywords" content="{{keywords}}"></head>模板代码片段宏函数macroiris.Django模板引擎能够很简便的定义一些宏函数代码片段。宏代码片段相当于一个函数,它只能调用从参数传入的变量。相似于应用include。不过macro有限定的作用域。如文章咱们给文章列表的文章item应用macro: 定义一个宏函数{% macro article_detail(article) %}<li class="item"> <a href="/article/{{article.Id}}" class="link"> <h5 class="title">{{article.Title}}</h5> </a></li>{% endmacro %}应用定义的宏函数{% for item in articles %} {{ article_detail(item) }}{% endfor %}同时宏函数还能够保留到独立的文件中,而后通过import来嵌套进来。当一个文件中蕴含多个宏函数,能够应用,将隔开间断引入多个宏函数。还能够应用as来设置别名: ...

January 6, 2021 · 8 min · jiezi

关于django:Django-Web开发之cookie

一.cookie1.1 什么是cookie?cookie是由服务器生成,存储在浏览器端的一小段文本信息。cookie的特点:1)以键值对形式进行存储。2)通过浏览器拜访一个网站时,会将浏览器存储的跟网站相干的所有cookie信息发送给该网站的服务器。3)cookie是基于域名平安的。4)cookie是有过期工夫的,如果不指定,默认敞开浏览器之后cookie就会过期。1.2 cookie的作用HTTP协定是无状态的,每次申请都是独立的,它的执行状况和后果与后面的申请和之后的申请没有任何的关系,而cookie就是为了满足人们对http申请状态的需要而诞生的。1.3 Django中cookie的应用设置cookie示例 def cookie_set(request): response = HttpResponse("<h1>设置Cookie</h1>") response.set_cookie('your_cookie', '你好') return response罕用: rep.set_cookie(key,value,...)rep.set_signed_cookie(key,value,salt='加密字符串', max_age=None, ...)获取cookie示例: def cookie_get(request): if 'your_cookie' in request.COOKIES: response = HttpResponse("获取Cookie") return response罕用: request.COOKIES['key']request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)总结办法形容rep.set_cookie(key,value,...)设置cookierep.set_signed_cookie(key,value,salt='加密字符串', max_age=None, ...)加盐的cookie设置,参数:1)key, 键2)value='', 值 3) max_age=None, 超时工夫 4) expires=None, 超时工夫(IE requires expires, so set it if hasn't been already.) 5) path='/', Cookie失效的门路,/ 示意根门路,非凡的:根门路的cookie能够被任何url的页面拜访 6) domain=None, Cookie失效的域名 7) secure=False, https传输 9) httponly=False 只能http协定传输,无奈被JavaScript获取(不是相对,底层抓包能够获取到也能够被笼罩)request.COOKIES['key']一般cookie获取request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)加盐的cookie获取,参数:1) default: 默认值 2) salt: 加密盐 3) max_age: 后盾管制过期工夫二.session对于敏感、重要的信息,倡议要储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息,这时候就要用到session。session将重要信息保留在服务器端,返回给客户端一个随机字符串,保留在cookie中。 ...

December 28, 2020 · 1 min · jiezi

关于django:DjangoMVT以及Django基础

一.框架框架是应答某类软件设计问题而产生的,它是由各个软件模块组成的,每个模块都有特定的性能,模块与模块之间通过相互配合来实现软件的开发。二. MVC 框架MVC简介MVC的理念: 分工,让专门的人去做专门的事。MVC的核心思想: 解耦。Web MVC框架模块性能M:Model, 和数据库进行交互。V:View, 产生html页面。C:Controller, 用于接管、解决申请,与M和V进行交互,返回应答。如下图所示 三.Django框架3.1Django简介Django ,遵循MVC思维,然而有本人的一个名词,叫做MVT。3.2Django中的MVTM:Model,模型, 和MVC中M性能雷同,同样是和数据库进行交互。V:View,视图, 相当于MVC中C,接管、解决申请,与M和T进行交互,返回应答。T:Template,模板, 和MVC中V性能雷同。如下图所示 假设baidu为Django开发 3.3Django装置pip install django// 指定版本 装置pip install django==2.2.23.4第一个Django我的项目建设我的项目django-admin startproject mysite我的项目目录.├── manage.py // django我的项目的管理文件└── mysite ├── __init__.py //__init__.py: 阐明是一个python包。 ├── settings.py //配置文件 ├── urls.py //url路由配置 └── wsgi.py // web服务器和Django交互的接口创立Django利用(app)cd mysite //进入django我的项目中python manage.py startapp testapp // testapp 为App的名字// 也能够应用django-admin startapp testapp 3.5配置文件 settings注册利用INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',# 'testapp', 晚期版本应用 'testapp.apps.TestappConfig', # 2.0以上版本应用 ]配置时区和语言环境LANGUAGE_CODE = 'zh-hans'TIME_ZONE = 'Asia/Shanghai'配置templates 目录TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [os.path.join(BASE_DIR, 'templates')], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, },]配置staticSTATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'),)数据库配置DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), }}3.6 视图在Django中,通过浏览器去申请一个页面时,应用视图函数来解决这个申请的,视图函数解决之后,要给浏览器返回页面内容。视图函数定义视图函数视图函数在views.py中定义。 ...

December 28, 2020 · 2 min · jiezi

关于django:Django-models-使用mysql的limit和offset功能

参考:Specifying limit and offset in Django QuerySet wont work-StackOverflowdjango官网文档 Use a subset of Python’s array-slicing syntax to limit your QuerySet to a certain number of results. This is the equivalent of SQL’s LIMIT and OFFSET clauses. For example, this returns the first 5 objects (LIMIT 5): Entry.objects.all()[:5] This returns the sixth through tenth objects (OFFSET 5 LIMIT 5): Entry.objects.all()[5:10] Negative indexing (i.e. Entry.objects.all()[-1]) is not supported. ...

December 24, 2020 · 1 min · jiezi

关于django:在VSCode中调试Django项目

如何在VSCode中欢快的调试Django我的项目代码,往下看~装置Django插件在VSCode扩大中,搜寻Django,点击install进行装置Djnao插件是针对Visual Studio代码的Django扩大,用于模板中语法提醒和补全、调试Django我的项目。 增加Django模块到vscode配置文件中依据截图上的程序进行增加。 调试程序准备就绪接下来,开始步入正题,应用VSCode调试程序。 点击调试抉择Python:Django点击调试,默认状况下,调试网址为127.0.0.1:8000端口启动调试后,插入断点、单步执行、变量监督,完满辅助你实现Django我的项目的代码调试。

December 21, 2020 · 1 min · jiezi

关于django:django报错NameError-name-‘include‘-is-not-defined

第一天学习django,报错NameError: name 'include' is not defined,来记录一下谬误 上网一查只用在django主动生成的包urls.py中退出 from django.conf.urls import include胜利运行 完满解决,在此感激喜爱海呀提供的博文

December 12, 2020 · 1 min · jiezi

关于django:三个生产级别的Django-异步应用实例

文章首发公众号「码农吴先生」, 欢送订阅关注。Django3.0 公布的时候,我尝试着用了下它的异步性能。过后它仅仅增加了对ASGI的反对(可见之前的文章 Django 3.0 异步试用分享,直到Django3.1的公布,才反对了视图和中间件的异步,然而要害的Django ORM层还是没有异步。Django生态对第三方异步的ORM反对又不是很敌对,这就导致很多用户面对Django的异步性能无从下手。 很过文章在形容Django view 和中间件的异步应用办法时,因为没有ORM的异步,在view中大多数用asyncio.sleep来代替,并没有实在的案例。这便进一步导致读者无从下手,认为Django 异步齐全没生产应用价值。这观点齐全是谬误的,现阶段Django 的异步性能齐全可用于生成。 下边是来自Arun Ravindran(<Django设计模式和最佳实际>作者) 的三个生产级别的Django 异步应用案例,供大家参考。 Django 异步的用例微服务调用现阶段,大多数零碎架构曾经从繁多架构进化为微服务架构,在业务逻辑中调用其余服务的接口成为常有的事件。Django 的异步view 在这种状况下,能够很大水平上进步性能。 让咱们看下作者的例子:通过两个微服务的接口来获取最初展现在home页的数据。 # 同步版本def sync_home(request): """Display homepage by calling two services synchronously""" context = {} try: # httpx 反对异步http client ,可了解为requests的降级异步版,齐全兼容requests 的api。 response = httpx.get(PROMO_SERVICE_URL) if response.status_code == httpx.codes.OK: context["promo"] = response.json() response = httpx.get(RECCO_SERVICE_URL) if response.status_code == httpx.codes.OK: context["recco"] = response.json() except httpx.RequestError as exc: print(f"An error occurred while requesting {exc.request.url!r}.") return render(request, "index.html", context)# 异步版本async def async_home_inefficient(request): """Display homepage by calling two awaitables synchronously (does NOT run concurrently)""" context = {} try: async with httpx.AsyncClient() as client: response = await client.get(PROMO_SERVICE_URL) if response.status_code == httpx.codes.OK: context["promo"] = response.json() response = await client.get(RECCO_SERVICE_URL) if response.status_code == httpx.codes.OK: context["recco"] = response.json() except httpx.RequestError as exc: print(f"An error occurred while requesting {exc.request.url!r}.") return render(request, "index.html", context)# 异步升级版async def async_home(request): """Display homepage by calling two services asynchronously (proper concurrency)""" context = {} try: async with httpx.AsyncClient() as client: # 应用asyncio.gather 并发执行协程 response_p, response_r = await asyncio.gather( client.get(PROMO_SERVICE_URL), client.get(RECCO_SERVICE_URL) ) if response_p.status_code == httpx.codes.OK: context["promo"] = response_p.json() if response_r.status_code == httpx.codes.OK: context["recco"] = response_r.json() except httpx.RequestError as exc: print(f"An error occurred while requesting {exc.request.url!r}.") return render(request, "index.html", context)同步版本很显然,当有一个服务慢时,整体的逻辑就会阻塞期待。服务的耗时依赖最初返回的那个接口的耗时。 ...

December 9, 2020 · 2 min · jiezi

关于django:djangorediscelery异步任务执行

一、装置redis参考redis文件夹下:redis装置 文档:redis装置.note链接:http://note.youdao.com/notesh...二、django工程配置1、装置依赖包pip install celery pip install celery-with-redis pip install django-celery2、配置settings.py文件 import djcelery #注册jdcelery INSTALLED_APPS = [ ... ,'djcelery', ] # celery 设置 # celery中间人 redis://redis服务所在的ip地址:端口/数据库号 BROKER_URL = 'redis://redis_ip:6379/0' # celery后果返回,可用于跟踪后果 CELERY_RESULT_BACKEND = 'redis://redis_ip:6379/0' # celery内容等音讯的格局设置,这里应用pickle,如果不应用,会序列化报错 CELERY_ACCEPT_CONTENT = ['pickle', ] CELERY_TASK_SERIALIZER = 'json' CELERY_RESULT_SERIALIZER = 'json' # celery时区设置,应用settings中TIME_ZONE同样的时区 CELERY_TIMEZONE = TIME_ZONE在工程目录下,创立celery.py文件# coding:utf-8 from __future__ import absolute_import, unicode_literals from celery import Celery from django.conf import settings import os# 获取以后文件夹名,即为该Django的我的项目名 project_name = os.path.split(os.path.abspath('.'))[-1] project_settings = '%s.settings' % project_name # 设置环境变量 os.environ.setdefault('DJANGO_SETTINGS_MODULE', project_settings)# 实例化Celery,网上很多教程这里都是没有设置broker造成启动失败 app = Celery('tasks', broker='redis://redis_ip:6379/0', backend='redis://redis_ip:6379/0') # 应用django的settings文件配置celery app.config_from_object('django.conf:settings') # Celery加载所有注册的利用 app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)在工程目录的__init__.py文件中增加:# 引入celery实例对象 # 肯定要增加在文件最后面,否则会报错 from __future__ import absolute_import, unicode_literals from .celery import app as celery_app __all__ = [celery_app]在对应app的目录下创立tasks.py文件留神:tasks.py文件肯定要创立在利用根目录下,且文件名固定,在该文件里增加你对应的后台任务代码,并注解@task ...

November 26, 2020 · 2 min · jiezi

关于django:使用djangocrontab建立定时任务

1、装置django-crontabpip install django-crontab2、在django我的项目settings.py中注册INSTALLED_APPS = [ ...... 'django_crontab', 'app_name']【留神】django_crontab肯定要注册在利用名之前,在这里是下划线,不是短横。 3、在settings.py中配置定时工作# 定时工作CRONJOBS = [ ('*/5 * * * *', 'RecomEvalBackend.job.syncMcnData.task'), ('*/5 * * * *', 'RecomEvalBackend.job.syncMcnData.task','>> test.log'), ('*/5 * * * *', 'RecomEvalBackend.job.syncMcnData.task',['param1','param2'],{'param3': 4},'>> test.log')]【留神】(1)这里的定时工作脚本,肯定是要放在利用文件夹下的;(2)RecomEvalBackend.job.syncMcnData.task这部分的写法应为:利用名.文件夹.文件名.办法名 4、如何在django中增加工作#django中增加定时工作python manage.py crontab add#django中移出定时工作python manage.py crontab remove#django中展现已增加的定时工作python manage.py crontab show#django中单次手动执行定时工作python manage.py crontab run <tash_hash_id>5、原理原理是django把定时工作增加到了linux的定时工作crond服务中。所以这里要求crond服务必须是开启的。查看服务器中定时工作命令: crontab -e查看crond服务状态: #查看状态service crond status#开启服务service crond start#敞开服务service crond stop#重启服务service crond restart6、其余注意事项(1)django-crontab不反对windows和mac零碎;在windows上执行会报错,如下: ... File "C:\Users\youngzhang\AppData\Local\Programs\Python\Python36\lib\site-packages\django_crontab\management\commands\crontab.py", line 4, in <module> from django_crontab.crontab import Crontab File "C:\Users\youngzhang\AppData\Local\Programs\Python\Python36\lib\site-packages\django_crontab\crontab.py", line 3, in <module> import fcntlModuleNotFoundError: No module named 'fcntl'

November 26, 2020 · 1 min · jiezi

关于django:真零基础Python开发web

Python开发web服务的劣势是开发效率高,可能只须要java五分之一的代码量。 Python搭建web服务有许多框架,本文介绍Django和bottle两个框架。 Django装置首先,装置该框架 装置胜利,版本是1.11.28. 框架的文件装置在\python27\Scripts目录下(搜寻电脑中Python装置目录下的Scripts就对了)。 建设我的项目先进入\python27\Scripts目录,建设我的项目jinanwx(名称轻易起) 同一个目录下能够看到新建设工程的目录 开发本人模块进入python27\Scripts\jinanwx\jinanwx。新建咱们本人的模块 jgotest01.py外面写简略的代码如下 模块性能就是返回个json格局后果。 批改urls模块而后须要改urls.py模块 目录文件如下 就这么简略,新建一个文件再批改一个文件,就成了。 启动服务回到上一级目录启动服务 启动胜利,浏览器拜访试试 bottle开发性能不是特地简单的web服务,能够思考应用bottle框架,它比Django轻量。bottle例子在Linux下演示。 装置应用bottle框架首先装置。一个指令搞定。 # pip install bottle 进入Python命令行import bottle,没报错就是胜利了。 代码我的web服务就一个文件bottleweb.py,代码如下,一些解释在代码的正文里 #coding=utf-8 from bottle import (run, route, get, post, put, delete, request, hook, response, static_file, app) import json import MySQLdb #本例子须要操作数据库,否则能够不写这行,这个数据库包pip预计装置不会胜利,我是用yum install MySQL-python胜利的 import sys reload(sys) sys.setdefaultencoding('utf8') import bottle app = bottle.default_app()#解决动态资源须要定义,没有动态资源能够不写这行 #搭建vue脚手架前后台联调时要上面两个@hook内容,否则会报跨域拜访资源的谬误 @hook('before_request') def validate(): REQUEST_METHOD = request.environ.get('REQUEST_METHOD') HTTP_ACCESS_CONTROL_REQUEST_METHOD = request.environ.get('HTTP_ACCESS_CONTROL_REQUEST_METHOD') if REQUEST_METHOD == 'OPTIONS' and HTTP_ACCESS_CONTROL_REQUEST_METHOD: request.environ['REQUEST_METHOD'] = HTTP_ACCESS_CONTROL_REQUEST_METHOD @hook('after_request') def enable_cors(): response.headers['Access-Control-Allow-Origin'] = '*' response.headers['Access-Control-Allow-Methods'] = 'GET,POST,PUT,DELETE,OPTIONS' response.headers['Access-Control-Allow-Headers'] = '*' @route('/test2020/dist/<path>')#动态资源在web服务下的地址,没放前端的动态资源这几个route和app.route能够不写 def stat(path): return static_file(path, root='./dist/') @app.route('/test2020/dist/static/js/<path>') def js(path): #这几个目录我写成这样是因为vue打包完后目录构造就是dist 外面static等等 return static_file(path, root='./dist/static/js/') @app.route('/test2020/dist/static/css/<path>') def css(path): return static_file(path, root='./dist/static/css/') @get('/test2020/date')#返回某个表中的日期,看sql你就明确了 def helloins(): db = MySQLdb.connect("127.0.0.1", "yourusername", "yourpassword", "yourDBname", charset='utf8' ) cursor = db.cursor() sql = "select DISTINCT date from testtable" print sql cursor.execute(sql) data = cursor.fetchall() jsondata={} results=[] for row in data: result = {} result['DATE'] = row[0] results.append(result) jsondata['code']=0 jsondata['datas']=results return jsondata #返回json格局为了不便前端vue接管解决,其实返回各种类型都能够 @get('/test2020/helloworld') def helloworld(): return 'hello world!' if __name__ == '__main__': run(host='0.0.0.0', port=2020, debug=True, reloader=True) bottleweb.py所在目录执行 ...

November 22, 2020 · 1 min · jiezi

关于django:一个py文件也能构建Django应用

明天在应用vue框架开发零碎的时候,须要用到后端接口,然而接口还没有开发。便想应用最简略的形式构建一个极简的API服务,因为自己偏爱Django框架,便想能不能用Django框架简略的构建想Flask那样的单文件web服务。果然,被我找到了,摘录分享给大家。 # app.py import osimport sysfrom dataclasses import dataclassfrom django.conf import settingsfrom django.core.wsgi import get_wsgi_applicationfrom django.http import HttpResponseRedirect, JsonResponsefrom django.urls import pathfrom django.utils.crypto import get_random_string# django 的配置文件,相当于 settings.py 配置文件,可间接在这里增加和删除# 下边曾经是最简的Django 启动须要的参数了settings.configure( DEBUG=(os.environ.get("DEBUG", "") == "1"), ALLOWED_HOSTS=["*"], # Disable host header validation ROOT_URLCONF=__name__, # Make this module the urlconf SECRET_KEY=get_random_string( 50 ), # We aren't using any security features but Django requires this setting MIDDLEWARE=["django.middleware.common.CommonMiddleware"],)# 应用dataclass 装璜器模仿了 model。@dataclassclass Character: name: str age: int def as_dict(self, id_): return { "id": id_, "name": self.name, "age": self.age, }# 列举数据,齐全能够间接应用字段来结构须要返回的数据characters = { 1: Character("Rick Sanchez", 70), 2: Character("Morty Smith", 14),}# Django View 局部,为不便简略间接应用 function base view def index(request): return HttpResponseRedirect("/characters/")def characters_list(request): return JsonResponse( {"data": [character.as_dict(id_) for id_, character in characters.items()]} )def characters_detail(request, character_id): try: character = characters[character_id] except KeyError: return JsonResponse( status=404, data={"error": f"Character with id {character_id!r} does not exist."}, ) return JsonResponse({"data": character.as_dict(character_id)})# Django route 局部,同 url.py urlpatterns = [ path("", index), path("characters/", characters_list), path("characters/<int:character_id>/", characters_detail),]# 构建 uwsgi 应用 application 可应用 uwsgi 等 WSGI 协定的软件启动。 app = get_wsgi_application()if __name__ == "__main__": # 引入命令行启动形式函数,不便间接启动测试, 同 manage.py 文件 from django.core.management import execute_from_command_line execute_from_command_line(sys.argv)间接运行如下命令即可启动服务: ...

November 16, 2020 · 1 min · jiezi

关于django:一代版本一代神利用Docker在Win10系统极速体验Django31真实异步Async任务

原文转载自「刘悦的技术博客」https://v3u.cn/a_id_177 就在去年(2019年),Django官网公布3.0版本,内核降级发表反对Asgi,这一重磅音讯让有数后盾研发人员欢呼雀跃,弹冠相庆。如获至宝之下,小伙伴们兴奋的开箱试用,后果却让人大跌眼镜:非但说好的外部集成Websocket没有呈现,就连原生的异步通信性能也只是个壳子,外部并未实现,很显著的换汤不换药,这让不少人转身投入了FastAPI的怀抱。不过一年之后,明天8月,Django3.1版本捷足先登,这个新版本终于一代封神,不仅反对原生的异步视图,同时也反对异步中间件,显著整了个大活。 本次咱们利用Docker制作一款基于Django3.1.1的我的项目镜像,理论体验一下Django原生异步的魅力。 首先在宿主机装置新版Django pip install Django3.1.1新建一个我的项目,名字为django31 django-admin.py startproject django31 . 进入我的项目目录能够发现,相熟的入口文件mange.py曾经隐没不见,新增了asgi.py文件用来启动我的项目,这里咱们应用异步服务器uvicorn来启动新版Django,而uvicorn对windows零碎反对不够敌对,所以应用Docker来构建一个运行镜像,简略不便,进入django31目录,新建Dockerfile: FROM python:3.7 WORKDIR /Project/django31 COPY requirements.txt ./ RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple COPY . . ENV LANG C.UTF-8 WORKDIR /Project CMD ["uvicorn", "django31.asgi:application","--host","0.0.0.0"]这里须要留神一点,Docker每创立一个容器,会在iptables中增加一个规定,每个容器都会在本机127.17.X.X范畴内调配一个地址,容器绑定的主机端口会映射到本机的127.17.X.X的容器抛出端口上。所以容器外部的我的项目绑定的ip不能是127.0.0.1,要绑定为0.0.0.0,这样绑定后容器外部app的理论ip由Docker主动调配,所以这里uvicorn启动参数须要用host强制绑定为0.0.0.0。 随后在我的项目中创立依赖文件requirements.txt: django==3.1.1 uvicorn httpx开始编译镜像文件: docker build -t 'django31' .编译胜利后大略1g左右 liuyue:django31 liuyue$ docker images REPOSITORY TAG IMAGE ID CREATED SIZE django31 latest e8afbbbb9305 30 minutes ago 919MB而后咱们来启动我的项目: docker run -it --rm -p 8000:8000 django31后盾显示启动顺利,绑定在容器内的0.0.0.0: ...

September 30, 2020 · 2 min · jiezi

了解-Django

装置pip3 install Django创立我的项目django-admin.py startproject {项目名称}如果提醒`You have 17 unapplied migration(s). Your project may not work properly until you apply the migrations for app(s): admin, auth, contenttypes, sessions.Run 'python manage.py migrate' to apply them.` 请换个我的项目名, 不能和py模块雷同如果提醒Django须要权限应用python manage.py migrate 启动我的项目python manage.py runserverorpython3 manage.py runserver 0.0.0.0:8000》如果应用sh运行我的项目失败, 把我的项目目录权限凋谢Permission denied···sudo chmod -R 777 {我的项目目录}··· 默认装置最新release版pip3 install Django装置开发版git clone https://github.com/django/django.gitpip3 install -e django/验证在py下 import djangoprint(django.get_version())//3.0.6或终端下 python3 -m django --version创立我的项目django-admin startproject mysite防止应用 Python 或 Django 的外部保留字来命名你的我的项目我的项目构造mysite/ manage.py mysite/ __init__.py settings.py urls.py asgi.py wsgi.py根目录可随便更改, 不影响我的项目manage.py: 一个让你用各种形式治理 Django 我的项目的命令行工具。你能够浏览 django-admin and manage.py 获取所有 manage.py 的细节。外面一层的 mysite/ 目录蕴含你的我的项目,它是一个纯 Python 包。它的名字就是当你援用它外部任何货色时须要用到的 Python 包名。 (比方 mysite.urls).mysite/__init__.py:一个空文件,通知 Python 这个目录应该被认为是一个 Python 包。如果你是 Python 初学者,浏览官网文档中的 更多对于包的常识")。mysite/settings.py:Django 我的项目的配置文件。如果你想晓得这个文件是如何工作的,请查看 Django settings 理解细节。mysite/urls.py:Django 我的项目的 URL 申明,就像你网站的“目录”。浏览 URL dispatcher 文档来获取更多对于 URL 的内容。mysite/asgi.py:作为你的我的项目的运行在 ASGI 兼容的Web服务器上的入口。浏览 如何应用 WSGI 进行部署理解更多细节。mysite/wsgi.py:作为你的我的项目的运行在 WSGI 兼容的Web服务器上的入口。浏览 如何应用如何应用 WSGI 进行部署 理解更多细节。创立利用 投票···python3 manage.py startapp polls······polls/ ...

July 16, 2020 · 7 min · jiezi

解决django-22与mysql兼容性问题

背景Django是一个优良的Python web框架,在应用Django2.2版本配置MySQL数据库时常会呈现上面的兼容问题: ImproperlyConfigured: mysqlclient 1.3.13 or newer is required在网上搜寻博客很多都是须要批改源码,既麻烦也不治标,上面举荐一种不批改源码的解决形式。 增加新版组件pip install mysqlclient如果你的我的项目根目录下有requirements.txt这个文件,间接关上增加mysqlclient即可。 移除旧版组建援用pip uninstall pymysql如果你的我的项目根目录下有requirements.txt这个文件,间接关上删除pymysql即可。关上与我的项目同名的目录下的__init__.py文件删掉上面两行代码 import pymysqlpymysql.install_as_MySQLdb()

July 14, 2020 · 1 min · jiezi

Django学习笔记

环境:DataBase:mysql5.7 communitymysql下载地址:https://dev.mysql.com/downloa...开发语言:Python 3.7.3 64bit下载mysql驱动: https://www.lfd.uci.edu/~gohl...admin后台优化:django-xadmindjango安装:pip install django==2.2 -i https://pypi.douban.com/simple镜像安装:https://pypi.douban.com/simple, 例: pip install django==2.2 -i https://pypi.douban.com/simplecaptcha插件:django simple captcha https://django-simple-captcha...redis windows:https://github.com/ServiceSta...redis python驱动:https://github.com/andymccurd...分页插件:django pure pagination https://github.com/jamespacil...技术点:format格式化>>>"{} {}".format("hello", "world") # 不设置指定位置,按默认顺序'hello world' >>> "{0} {1}".format("hello", "world") # 设置指定位置'hello world' >>> "{1} {0} {1}".format("hello", "world") # 设置指定位置'world hello world'http数据传给前端from django.http import HttpResponseRedirect, JsonResponsereturn JsonResponse({})FORM 字段单独验证class RegisterPostForm(forms.Form): mobile = forms.CharField(required=True, min_length=11, max_length=11) code = forms.CharField(required=True, min_length=4, max_length=4) password = forms.CharField(required=True) # 验证手机号是否已注册 def clean_mobile(self): mobile = self.data.get("mobile") user = UserProfile.objects.filter(mobile=mobile) if user: raise forms.ValidationError("该手机号已被注册") return mobile防止basemodel字段生成表class BaseModel(models.Model): add_time = models.DateTimeField(default=datetime.now, verbose_name="添加时间") class Meta: # 防止BaseModel生成表 abstract = Truedjango内置用户密码加密方法user = UserProfile(mobile=mobile)user.set_passdjangoword(password) # set_password生成加密后的密码HttpResponseRedirect页面重定向跳转if user is not None: # 查询到用户 login(request, user) # HttpResponseRedirect页面重定向 return HttpResponseRedirect(reverse("index"))model外键定义class Lesson(BaseModel): # on_delete表示对应的外键数据被删除后,当前的数据应该怎么办 # 值为models.SET_NULL不级联删除,还需参数null=True, blank=True。值为models.CASCADE会级联删除 # course = models.ForeignKey(Course, on_delete=models.SET_NULL, null=True, blank=True) course = models.ForeignKey(Course, on_delete=models.CASCADE) name = models.CharField(verbose_name="章节名", max_length=100) learn_times = models.IntegerField(verbose_name="学习时长(分钟数)", default=0) class Meta: verbose_name = "课程章节" verbose_name_plural = verbose_name def __str__(self): return self.name分页class CourseListView(View): def get(self, request, *args, **kwargs): # 获取课程列表 all_courses = Course.objects.all().order_by("-add_time") # 对课程数据进行分页 try: page = request.GET.get('page', 1) except PageNotAnInteger: page = 1 p = Paginator(all_courses, per_page=5, request=request) courses = p.page(page) return render(request, "course-list.html", { "all_courses": courses })# 注意 all_courses.object_list{% for course in all_courses.object_list %}{% endfor %}<div class="pageturn"> <ul class="pagelist"> {% if all_courses.has_previous %} <li class="long"><a href="?{{ all_courses.previous_page_number.querystring }}">上一页</a> </li> {% endif %} {% for page in all_courses.pages %} {% if page %} {% ifequal page all_courses.number %} <li class="active"><a href="?{{ page.querystring }}">{{ page }}</a></li> {% else %} <li><a href="?{{ page.querystring }}" class="page">{{ page }}</a></li> {% endifequal %} {% else %} <li class="none">...</li> {% endif %} {% endfor %} {% if all_courses.has_next %} <li class="long"><a href="?{{ all_courses.next_page_number.querystring }}">下一页</a></li> {% endif %} </ul></div>取外键属性值<!--外键查找属性 查找课程外键课程机构的名称--><a href="course-detail.html"> <span class="fl">来自{{ course.course_org.name }}</span></a>model数据查询倒序# order_by 倒序字段前加“-”all_courses = Course.objects.all().order_by("-add_time")template对model charfiled choices取值# modelclass Course(BaseModel): degree = models.CharField(verbose_name="难度", choices=(("cj", "初级"), ("zj", "中级"), ("gj", "高级")), max_length=2)# html难度:<i class="key">{{ course.get_degree_display }}</i>template media_url拼接<img src="{{ course.image.url }}"/># 等同于<img src="{{ MEDIA_URL }}{{ course.image }}"/>url中设置参数字段获取urlpatterns = [ url(r'(?P<course_id>\d+)/detail/$', CourseDetailView.as_view(), name='detail'),]class CourseDetailView(View): def get(self, request, course_id, *args, **kwargs): pass字典循环取数据快捷写法user_courses = UserCourse.objects.filter(course=course)user_ids = [user_course.user.id for user_course in user_courses]template for循环取索引下标{% for teacher in hot_teachers %}# forloop.counter0 会得到从0开始计算的下标# forloop.counter 会得到从1开始计算的下标<span class="num fl">{{ forloop.counter }}</span>{% endfor %}template过滤处理<input type="text" value="{{ user.birthday|default_if_none:''|date:'Y-m-d' }}"/>

July 7, 2020 · 2 min · jiezi

Djangoimagekit的使用

1、安装要在 Django 使用 ImageField 模块,必须先安装第三方库 Pillow: pip install pillowpip install django-imagekit完成上述步骤后,在 Django 项目的 settings.py 文件中的 INSTALLED_APPS 添加上 imagekit。 现在准备工作全部完成,可以在项目中使用 django-imagekit 来处理图片了。 2、简单例子我们在 modles 中这样使用 django-imagekit: from django.db import modelsfrom imagekit.models import ImageSpecFieldfrom imagekit.processors import ResizeToFillclass Profile(models.Model): name = models.CharField(max_length = 50) # 原图 picture = models.ImageField(upload_to = 'test_pictures') # 注意:ImageSpecField不会生成数据库中的表 # 处理后的图片 picture_90x90 = ImageSpecField( source="picture", processors=[ResizeToFill(90, 90)], # 处理后的图像大小 format='JPEG', # 处理后的图片格式 options={'quality': 95} # 处理后的图片质量 ) def __str__(self): return self.name图片上传后会根据我们的设定生成相应的处理后的图片。 ...

July 5, 2020 · 1 min · jiezi

Django中F函数的使用

开发个人博客时,统计每篇文章浏览量的逻辑通常是这样写的: post = Post.objects.get(...)post.views += 1post.save()上面的语句已经相当简短了,但实际上还有更好的办法,就是运用 F 函数: from django.db.models import Fpost = Post.objects.get(...)post.views = F('views') + 1post.save()看起来似乎都差不多,但是用 F 函数有几个显著的好处: 减少了操作次数。post.view += 1 是 Python 在内存中操作的,然后再从内存把数据更新到数据库;而 F('views') + 1 是直接操作的数据库,减少了一个操作层级。避免竞争。竞争是指多个 Python 线程同时对同一个数据进行更新,post.view += 1 就有可能丢失其中的某些更新操作,而 F('views') + 1 由于是直接操作数据库,不会有丢失数据的问题。注意,正因为 F 函数没有在内存中操作,因此更新完数据后需要重新刷新内存中的模型对象: ...post.save()# 重新取值post = Post.objects.get(...)或者这样: ...post.save()# 重新取值post.refresh_from_db()Done! 除此之外,F 函数还支持跨字段的查找: # models.pyclass Age(models.Model): year = models.IntegerField(default=6) month = models.IntegerField(default=10)# --------------# 获取所有 year > month 的数据res = Age.objects.filter(year__gt=F('month'))F 函数支持加,减,乘,除,取模和幂运算: ...

July 5, 2020 · 1 min · jiezi

Django处理事务transaction

有些时候我们需要对数据库进行一连串的操作,如果其中某一个操作失败,那么其他的操作也要跟着回滚到操作以前的状态。 举个例子。某天你到银行存了 100 块钱,所以你的账户的数据库表就应该减去 100 块,而银行的账户上增加 100 块。但如果数据库在执行银行账户增加 100 块时操作失败了,岂不是平白无故损失掉 100 块钱,那你不得把银行屋顶给拆了。 这种情况下就需要用到事务这个概念了,即把一组操作捆绑到一起,大家生死与共,要么都成功,要么都失败,结成人民统一战线。 Django 里如何实现事务?看下面的例子: # models.pyfrom django.db import modelsclass Student(models.Model): """学生""" name = models.CharField(max_length=20)class Info(models.Model): """学生的基本情况""" age = models.IntegerField()class Address(models.Model): """学生的家庭住址""" home = models.CharField(max_length=100)有三个模型,Student 为学生、Info 为学生的基本情况、Address 为学生的住址。假设这三个模型必须同时创建,否则数据就是不完整的。 我们可以这样写视图: def create_student(request): student = Student.objects.create(name='张三') info = Info.objects.create(age=19) address = Address.objects.create(home='北京') return HttpResponse('Create success...')很正常对吧。接下来让程序故意引发错误: def create_student(request): student = Student.objects.create(name='张三') info = Info.objects.create(age=19) # 引发错误 oh_my_god = int('abc') address = Address.objects.create(home='北京') return HttpResponse('Create success...')这就有问题了,前面的 Student 和 Info 都正常保存进数据库了,但是 Address 却由于前一句报错而没有执行创建,因此学生信息就变成了不完整的垃圾数据了。 ...

July 5, 2020 · 1 min · jiezi

Django-中-Aggregation聚合的使用

Django 的 filter、exclude 等方法使得对数据库的查询很方便了。这在数据量较小的时候还不错,但如果数据量很大,或者查询条件比较复杂,那么查询效率就会很低。 提高数据库查询效率可以通过原生 SQL 语句来实现,但是它的缺点就是需要开发者熟练掌握 SQL。倘若查询条件是动态变化的,则编写 SQL 会更加困难。 对于以便捷著称的 Django,怎么能忍受这样的事。于是就有了Aggregation聚合。 聚合最好的例子就是官网给的案例了: # models.pyfrom django.db import modelsclass Author(models.Model): name = models.CharField(max_length=100) age = models.IntegerField()class Publisher(models.Model): name = models.CharField(max_length=300)class Book(models.Model): name = models.CharField(max_length=300) pages = models.IntegerField() price = models.DecimalField(max_digits=10, decimal_places=2) rating = models.FloatField() authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher, on_delete=models.CASCADE) pubdate = models.DateField()class Store(models.Model): name = models.CharField(max_length=300) books = models.ManyToManyField(Book)接下来可以这样求所有书籍的平均价格: >>> from django.db.models import Avg, Max, Min>>> Book.objects.all().aggregate(Avg('price')){'price__avg': Decimal('30.67')}实际上可以省掉 all() : ...

July 5, 2020 · 1 min · jiezi

Django消息通知djangonotificationshq的使用

一、安装pip install django-notifications-hq二、配置1. settings.py文件INSTALLED_APPS = ( 'django.contrib.auth', ... 'notifications', ...)2. 项目urls.py文件import notifications.urlsurlpatterns = [ ... url('^inbox/notifications/', include(notifications.urls, namespace='notifications')), ...]三、数据库迁移python manage.py migrate notifications四、使用一般生成的通知最好在单独的信号中完成,Django有自带的信号处理方式,具体可参考Django官方文档signals章节示例代码: from django.dispatch import receiverfrom django.db.models.signals import post_savefrom comment.models import Commentfrom notifications.signals import notifyfrom django.utils.html import strip_tags@receiver(post_save, sender=Comment)def send_notification(sender, instance, **kwargs): # 发送站内消息 if instance.reply_to is None: # 评论 recipient = instance.content_object.get_user() if instance.content_type.model == 'blog': blog = instance.content_object verb = '{0} 评论了你的博客《{1}》'.format(instance.user.username, blog.title) else: raise Exception('unkown comment object type') else: # 回复 recipient = instance.reply_to verb = '{0} 回复了你的评论“{1}”'.format( instance.user.username, strip_tags(instance.parent.text) ) notify.send(instance.user, recipient=recipient, verb=verb, action_object=instance)也可在项目任何地方生成通知示例代码: ...

July 4, 2020 · 1 min · jiezi

java-爬虫模

as;dkakda;dkakdakdadjsdkaksdnasdnadsadkandakndkvadnkadsnakdakdnakdakda;ddkakdnk;adna;dwwieenkdnakna;ksddkna;kd;adsdkjnasdjalskdmaklda

May 30, 2020 · 1 min · jiezi