当前位置: 首页 > news >正文

海东企业网站建设wordpress安装主题需要主机名

海东企业网站建设,wordpress安装主题需要主机名,wordpress信息修改,理财网站免费建设频率超高的问题 Redis的问题虚拟环境mysqlcient和pymysql短信服务#xff0c;一期用的是腾讯云短信 虚拟环境 可以用来创建虚拟环境的#xff1a; virtualenv这个模块#xff0c;简单易上手#xff0c;推荐 小白不建议#xff0c;conda#xff0c;如果大家用这个一期用的是腾讯云短信 虚拟环境 可以用来创建虚拟环境的 virtualenv这个模块简单易上手推荐 小白不建议conda如果大家用这个简单用的就miniconda比较简洁Anaconda比较全。都有一个包管理器叫做conda相当于pip你可以用conda命令来管理虚拟环境它比virtualenv要好用。 参考https://www.cnblogs.com/Neeo/articles/9574705.html#%E8%99%9A%E6%8B%9F%E7%8E%AF%E5%A2%83%E7%AE%A1%E7%90%86 miniconda官网https://docs.conda.io/en/latest/miniconda.html#windows-installers 关于这个virtualenv的坑1中文路径 坑千万不要将你的虚拟环境创建在包含中文或者其他特殊字符的目录下。 包含中文路径下创建并使用虚拟环境有问题 在不包含中文路径下创建并使用虚拟环境没问题。 建议 激活虚拟环境之后下载模块之前都要去pip -V确认下虚拟环境激活没有。 关于这个virtualenv的坑2创建的虚拟环境无法使用 现象使用虚拟环境运行Django项目提示当前虚拟环境中没有找到Django即没有找到Django这个模块但Django模块是下载好的。 就是死活读不到。 如何解决。 第一步先将虚拟环境中的项目依赖导出到requirements.txt文件中。 (venv) D:\day7pip freeze requiements.txt(venv) D:\day7第二步从本地将你的虚拟环境(文件夹)删除。 第三步从新创建一个虚拟环境 D:\day7virtualenv venv第四步激活虚拟环境并且从requirements.txt文件中将项目依赖下载到当前虚拟环境中。 第五步就是在pycharm中重新配置解释器应用上虚拟环境。 关于这个virtualenv的坑3虚拟环境的名字有问题 通常创建的虚拟环境名字叫做env或者venv但极个别的情况venv这个虚拟环境名字不能用现象也是虚拟环境无法激活。 解决办法删掉这个虚拟环境再重新创建的时候换个别的名字比如说abc。 额外的卸载重装python解释器 如果是Windows不要直接删而是从系统设置中去卸载 关于pycharm无法创建Django项目 如果你是这样创建Django项目的 但是创建时遇到error错误了 除了这个问题还有个就是这种创建Django项目的方式默认下载的Django是最新版的。如果你的项目必须要求低版本的或者其他指定版本这种方式就不太好了。 针对以上报错问题还有无法选择版本的问题我通常是建议不要用pycharm提供的快速创建Django项目的功能了。 我们自己来在终端中执行 # 1. 选择项目要创建在哪个目录下就在哪个目录下打开终端手动创建项目名 D:\day7mkdir demo# 2. 切换到项目名中也就是项目根目录下 D:\day7cd demo# 3. 创建该项目所需的虚拟环境 D:\day7\demovirtualenv venv created virtual environment CPython3.10.9.final.0-64 in 364mscreator CPython3Windows(destD:\day7\demo\venv, clearFalse, no_vcs_ignoreFalse, globalFalse)seeder FromAppData(downloadFalse, pipbundle, setuptoolsbundle, wheelbundle, viacopy, app_data_dirC:\Users\12061\AppData\Local\pypa\virtualenv)added seed packages: pip23.1.2, setuptools68.0.0, wheel0.40.0activators BashActivator,BatchActivator,FishActivator,NushellActivator,PowerShellActivator,PythonActivator# 4. 激活虚拟环境 D:\day7\demo.\venv\Scripts\activate# 5. 确认是否激活虚拟环境 (venv) D:\day7\demopip -V pip 23.1.2 from D:\day7\demo\venv\lib\site-packages\pip (python 3.10)# 6. 安装指定版本的Django (venv) D:\day7\demopip install django4.2.3 Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple Collecting django4.2.3Using cached https://pypi.tuna.tsinghua.edu.cn/packages/d4/83/227ebf197e413f3599cea96dddc7d6b8ff220310cc5b40dd0f1a15e5a9d1/Django-4.2.3-py3-none-any.whl (8.0 MB) Collecting asgiref4,3.6.0 (from django4.2.3)Using cached https://pypi.tuna.tsinghua.edu.cn/packages/9b/80/b9051a4a07ad231558fcd8ffc89232711b4e618c15cb7a392a17384bbeef/asgiref-3.7.2-py3-none-any.whl (24 kB) Collecting sqlparse0.3.1 (from django4.2.3)Using cached https://pypi.tuna.tsinghua.edu.cn/packages/98/5a/66d7c9305baa9f11857f247d4ba761402cea75db6058ff850ed7128957b7/sqlparse-0.4.4-py3-none-any.whl (41 kB) Collecting tzdata (from django4.2.3)Using cached https://pypi.tuna.tsinghua.edu.cn/packages/d5/fb/a79efcab32b8a1f1ddca7f35109a50e4a80d42ac1c9187ab46522b2407d7/tzdata-2023.3-py2.py3-none-any.whl (341 kB) Collecting typing-extensions4 (from asgiref4,3.6.0-django4.2.3)Using cached https://pypi.tuna.tsinghua.edu.cn/packages/ec/6b/63cc3df74987c36fe26157ee12e09e8f9db4de771e0f3404263117e75b95/typing_extensions-4.7.1-py3-none-any.whl (33 kB) Installing collected packages: tzdata, typing-extensions, sqlparse, asgiref, django Successfully installed asgiref-3.7.2 django-4.2.3 sqlparse-0.4.4 typing-extensions-4.7.1 tzdata-2023.3[notice] A new release of pip is available: 23.1.2 - 23.2.1 [notice] To update, run: python.exe -m pip install --upgrade pip# 7. 确认的Django是否安装成功 (venv) D:\day7\demodjango-admin --version 4.2.3# 8. 创建项目 下面命令中的点表示创建好的项目文件都保存在项目根目录下 (venv) D:\day7\demodjango-admin startproject demo .# 9. 创建app # 补充创建app的两种方式 # 1. django-admin startapp api # django-amdin命令创建 # 2. 在项目根目录下执行python manage.py startapp app01 # 这是第二种方式 # 推荐哪个你可以先使用第二种万一出了问题再使用第一中尝试。 (venv) D:\day7\demodjango-admin startapp api# 10. 测试项目能否正常运行 (venv) D:\day7\demopython manage.py runserver Watching for file changes with StatReloader Performing system checks...System check identified no issues (0 silenced).You have 18 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. July 30, 2023 - 09:49:01 Django version 4.2.3, using settings demo.settings Starting development server at http://127.0.0.1:8000/ Quit the server with CTRL-BREAK.[30/Jul/2023 09:49:03] GET / HTTP/1.1 200 10664 Not Found: /favicon.ico [30/Jul/2023 09:49:03] GET /favicon.ico HTTP/1.1 404 2108pycharm从本地打开项目然后添加当前虚拟环境到pycharm的解释器配置中了。 检查Django项目的配置是否正确。 检查settings配置手动注册app。 关于模板文件夹的配置手动创建模板文件夹。 关于Django纯净版的问题 首先Django纯净版的本身没问题但大家老是会遇到相关的问题。 我不建议初学者用这个Django纯净版因为你不知道有些模块或者三方框架内部有用到我们注释掉的这些组件导致运行时可能出现一些报错你也解决不了。 建议所有组件都用上功能都有我们可以不用但如果有三方组件用到了它内部就不报错了。 关于mysqlclient和pymysql的相爱相杀 超频问题我项目中用mysql我用哪个模块。 建议先使用mysqlclient pip install mysqlclient如果下载成功不报错其它的一点都不用配置项目就能正常使用了。 如果下载过程中出现报错或者使用过程中出现mysql的连接问题排查了settings配置没问题之后我们不纠结也不排查mysqlclient的错误。而是直接改用pymysql。 pip install pymysqlpymysql和mysqlclient的使用没有任何区别就是pymysql比mysqlclient多了一个配置。 那就是pymysql在下载之后需要你在settings.py同级目录下的__init__.py文件中添加下面两行代码就ok了。 import pymysql pymysql.install_as_MySQLdb()项目中集成云短信 原来推荐使用腾讯云短信。但最近发现腾讯云短信的功能开通大家可能会卡在签名这里因为要认证。比如说企业资质我们个人开发学习阶段不容易开通 导致用不了。 这是咱们一期项目中同学遇到的关于短信的主要问题。 我个人建议如果你自己学习阶段去开通腾讯云短信服务卡在某个环节进行不下去了。那么你没比较纠结。可以专用其它厂家提供的短信服务。 云通讯。互亿无限。 其实用哪个厂家的短信服务没关系你会发现其实都没几行代码。 参考https://www.cnblogs.com/Neeo/articles/16672659.html 腾讯云短信 下载模块 pip install --upgrade tencentcloud-sdk-python创建好应用并获取应用ID打开连接https://console.cloud.tencent.com/smsv2/app-manage/detail/1400793930遇到登录就微信扫码登录。 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 准备好秘钥用于获取SecretId和SecretKey秘钥管理https://console.cloud.tencent.com/cam/capi 签名准备好签名这一步有点麻烦因为需要审核。好多学生卡在这里了。连接https://console.cloud.tencent.com/smsv2/csms-sign 准备好模板比如| 验证码为{1}您正在登录若非本人操作请勿泄露。其中的{1}就是我们将来要自定义 模板管理https://console.cloud.tencent.com/smsv2/csms-template 下面是我整理好的腾讯云短信发送的示例可以拷贝到你的项目中进行使用。 # -*- coding utf-8 -*- import random import string from tencentcloud.common import credential from tencentcloud.sms.v20210111 import sms_client, models# 注意下面写法是固定的你只需要按照上面给的链接中获取对应的值来修改即可# 下面这俩值从这个页面中获取https://console.cloud.tencent.com/cam/capi SecretId AKIDQdZFemCGdlcCo9sQ9sKkwriIq776rUu4 SecretKey FEvLZWBZgX7JFzRcW8VbgU7UZOvCuc3Hcred credential.Credential(secret_idSecretId, # 注意必须以关键字的形式传参secret_keySecretKey # 注意必须以关键字的形式传参 ) # secretId secretKey client sms_client.SmsClient(cred, ap-guangzhou) # 固定写法无需变动req models.SendSmsRequest() # 固定写法无需变动# 应用id注意这个是你创建的应用id是这个链接https://console.cloud.tencent.com/smsv2/app-manage 中的应用ID # 不是密钥页面的APPID既不是这个页面的IDhttps://console.cloud.tencent.com/cam/capi req.SmsSdkAppId 1400793930# 模板相关的值从这个页面中获取https://console.cloud.tencent.com/smsv2/csms-template req.SignName 张开与老虎 # 模板签名 req.TemplateId 575000 # 模板id(可以有多套模板进行更换这样发送的短信内容就可以改变了)# 下面就是结合模板填写具体要发送的验证码和手机号了 code .join(random.sample(string.digits, 6)) # 随机生成的6位验证码 print(code) # 671093 req.TemplateParamSet [code] # 发送的6位验证码 req.PhoneNumberSet [8618211101742] # 目标手机号resp client.SendSms(req) # 发送 print(resp){SendStatusSet: [{SerialNo: 2433:326237685316756579077330174, PhoneNumber: 8618211101742, Fee: 1, SessionContext: , Code: Ok, Message: send success, IsoCode: CN}], RequestId: 25147cb8-9abd-4100-bdbb-bb61cd3c2828 }# 你的手机号应该接收到了短信 【张开与老虎】验证码为671093您正在登录若非本人操作请勿泄露。优化一版 # -*- coding utf-8 -*- import random import string from tencentcloud.common import credential from tencentcloud.sms.v20210111 import sms_client, models# 注意下面写法是固定的你只需要按照上面给的链接中获取对应的值来修改即可# 下面这俩值从这个页面中获取https://console.cloud.tencent.com/cam/capi SecretId AKIDQdZFemCGdlcCo9sQ9sKkwriIq776rUu4 SecretKey FEvLZWBZgX7JFzRcW8VbgU7UZOvCuc3Hdef getcode(num):# 下面就是结合模板填写具体要发送的验证码和手机号了code .join(random.sample(string.digits, num)) # 根据需要随机生成的指定位数的验证码print(code) # 671093return codedef send_sms(phone, temp_id):cred credential.Credential(secret_idSecretId, # 注意必须以关键字的形式传参secret_keySecretKey # 注意必须以关键字的形式传参) # secretId secretKeyclient sms_client.SmsClient(cred, ap-guangzhou) # 固定写法无需变动req models.SendSmsRequest() # 固定写法无需变动# 应用id注意这个是你创建的应用id是这个链接https://console.cloud.tencent.com/smsv2/app-manage 中的应用ID# 不是密钥页面的APPID既不是这个页面的IDhttps://console.cloud.tencent.com/cam/capireq.SmsSdkAppId 1400793930# 模板相关的值从这个页面中获取https://console.cloud.tencent.com/smsv2/csms-templatereq.SignName 张开与老虎 # 模板签名req.TemplateId temp_id # 模板id(可以有多套模板进行更换这样发送的短信内容就可以改变了)req.TemplateParamSet [getcode(num4)] # 发送的4位验证码req.PhoneNumberSet [f86{phone}] # 目标手机号resp client.SendSms(req) # 发送# print(333, resp.SendStatusSet[0].__dict__)# print(333, resp.SendStatusSet[0].__dict__[_Code])# 我这里发送太频繁了导致下面代码没法测了后续你们自己可以根据打印内容进行测试,主要就是判断发送成功还是失败if resp.SendStatusSet[0].__dict__[_Code] OK:# 短信发送成功print(11)return Trueelse:# 短信发送失败print(22)return False{SendStatusSet: [{SerialNo: 2433:326237685316756579077330174, PhoneNumber: 8618211101742, Fee: 1, SessionContext: , Code: Ok, Message: send success, IsoCode: CN}], RequestId: 25147cb8-9abd-4100-bdbb-bb61cd3c2828}# 你的手机号应该接收到了短信【张开与老虎】验证码为671093您正在登录若非本人操作请勿泄露。# 更换不同的模板id其它代码可以不变就能动态的发送不同的短信【张开与老虎】您的动态验证码为036724您正在进行密码重置操作如非本人操作请忽略本短信# 发送太频繁了报错了{_SendStatusSet: [{SerialNo: , PhoneNumber: 8618211101742, Fee: 0, SessionContext: , Code: LimitExceeded.PhoneNumberThirtySecondLimit, Message: the number of SMS messages sent from a single mobile number within 30 seconds exceeds the upper limit, IsoCode: CN}], _RequestId: 7bd7d567-61a2-479a-b37c-b342f79792aa} if __name__ __main__:res send_sms(18211101742, 575001) # 第二个参数是模板id不同的模板id可以发送不同的短信# 伪代码# if not res:# return JsonResponse({code: 1000, msg:短信发送失败})# # 接着往下写短信发送成功的代码云通信短信(如果搞不定腾讯云短信推荐这个) 为啥推荐因为这个简单。 参考https://www.cnblogs.com/Neeo/articles/16672659.html#%E5%AE%B9%E8%81%94%E4%BA%91%E7%9F%AD%E4%BF%A1 注册 https://console.yuntongxun.com/user/reg/init 登录 登录成功自动跳转到控制台主页。遇到下面的认证提示直接点击关闭即可。 进入控制台首页https://console.yuntongxun.com/member/main 应用 用默认的就就行了。 模板部分 想要自定义模板需要充值5000块算了吧用默认的就行了免费。 手机号 测试阶段你只能向下面预留的手机号发送测试短信。 具体使用 常见报错 {‘statusCode’: ‘112310’, ‘statusMsg’: ‘【短信】应用未上线模板短信接收号码外呼受限’} Response body: {statusCode:112310,statusMsg:【短信】应用未上线模板短信接收号码外呼受限}{‘statusCode’: ‘161125’, ‘statusMsg’: ‘请输入1到4位的数字’} # -*- coding utf-8 -*- import random import json from ronglian_sms_sdk import SmsSDKdef send_sms(mobile, datas, tid1):发送短信params tid: 模板ID默认测试使用1params mobile: 接收短信的手机号多个手机号使用都逗号隔开单个号码 mobile13312345678多个号码 mobile13312345678,13312345679,....params datas: 短信模板的参数列表例如短信模板为 【云通讯】您的验证码是{1}请于{2}分钟内正确输入。则datas(3456,2,)最终发送的短信为【云通讯】您的验证码是{3456}请于{5}分钟内正确输入。# 下面的配置根据你的控制台首页主账号那里获取RONGLIANYUN_CONFIG {# 下面这三个值都可以从控制台首页的开发者主账号中进行获取accId: 2c94811c87fb7ec601881e50a8ed0b39, # 对应ACCOUNT SIDaccToken: 23d2e5f9f7694d9e888eb2a6848dae42, # 对应AUTH TOKENappId: 2c94811c87fb7ec601881e50aa210b40, # 对应AppID(默认)reg_tid: 1, # 注册短信验证码的模板ID测试阶段固定为1不需要修改# 下面两个根据需要修改sms_expire: 120, # 短信有效期单位秒(s)这是真正的超时时间注意和datas(3456,2,)中第二个参数进行换算保持一致sms_interval: 60, # 短信发送的冷却时间单位秒(s)}# 不需要修改sdk SmsSDK(RONGLIANYUN_CONFIG.get(accId), RONGLIANYUN_CONFIG.get(accToken), RONGLIANYUN_CONFIG.get(appId))# 发送短信resp sdk.sendMessage(str(tid), mobile, datas)# 拿到结果response json.loads(resp)print(response, type(response))Sign plaintext: 2c94811c87fb7ec601881e50a8ed0b3923d2e5f9f7694d9e888eb2a6848dae4220230524140059Authorization plaintext: 2c94811c87fb7ec601881e50a8ed0b39:20230524140059Request url: https://app.cloopen.com:8883/2013-12-26/Accounts/2c94811c87fb7ec601881e50a8ed0b39/SMS/TemplateSMS?sig6FB880CDC9671A41674C17DE348D300BRequest headers: {Content-Type: application/json;charsetutf-8, Accept: application/json, Accept-Charset: UTF-8, Authorization: bMmM5NDgxMWM4N2ZiN2VjNjAxODgxZTUwYThlZDBiMzk6MjAyMzA1MjQxNDAwNTk}Request body: {to: 18211101742, appId: 2c94811c87fb7ec601881e50aa210b40, templateId: 1, datas: [4653, 2]}Response body: {statusCode:000000,templateSMS:{smsMessageSid:8bcc77c455084a6b8d52983e95f10977,dateCreated:20230524140100}}{statusCode: 000000, templateSMS: {smsMessageSid: 8bcc77c455084a6b8d52983e95f10977, dateCreated: 20230524140100}} class dict# statusCode是000000表示发送成功# 手机上接收到的短信长这样【云通讯】您使用的是云通讯短信模板您的验证码是2491请于2分钟内正确输入变量仅支持1-4位数字return response.get(statusCode) 000000def get_code(num4):生成指定位数的验证码如果不传值就默认生成4位的验证码:param num: 要生成几位的验证码:return: 生成的验证码return random.randint(int(1{}.format(0 * (num - 1))),int(9{}.format(9 * (num - 1))))if __name__ __main__:res send_sms(mobile18211101742, # 这个手机号必须在你在容联云中填写的那个3个测试手机号中datas(get_code(4), 2), # 元组的第一个参数是4位的验证码,注意免费测试的只支持发送4位的验证码不支持6位的第二个参数是短信模板中替换为请于{2}分钟内正确输入tid1 # 这个模板id目前测试阶段固定为1)# 伪代码# if not res:# return JsonResponse({code: 1000, msg:短信发送失败})# # 接着往下写短信发送成功的代码互亿无线106短信 实名认证 1. 注册 实名注册https://user.ihuyi.com/new/register.html?e400 2. 登录之后在控制台进行个人认证 短信demo 首先准备这两个值 官网链接https://user.ihuyi.com/new/sms/overview 代码 # -*- coding utf-8 -*- # python3 # 接口类型互亿无线触发短信接口支持发送验证码短信、订单通知短信等。 # 账户注册请通过该地址开通账户https://user.ihuyi.com/new/register.html # 注意事项 # 1调试期间请用默认的模板进行测试默认模板详见接口文档 # 2请使用 用户名 及 APIkey来调用接口APIkey在会员中心可以获取 # 3该代码仅供接入互亿无线短信接口参考使用客户可根据实际需要自行编写 import json import random import urllib.parse import urllib.requestdef get_code(num4):生成指定位数的验证码如果不传值就默认生成4位的验证码:param num: 要生成几位的验证码:return: 生成的验证码return random.randint(int(1{}.format(0 * (num - 1))),int(9{}.format(9 * (num - 1))))def send_sms(mobile, code_num4):发送短信验证码:param mobile: 你要发给谁:param code_num: 发送几位的验证码:return:# 接口地址咱们不需要更改url http://106.ihuyi.com/webservice/sms.php?methodSubmit# 定义请求的数据values {account: C05062020, # 这个是对应的APIIDpassword: aff16e275e46618efd14f21b00d6de91, # 这个是对应的APIKEYmobile: mobile, # 发给谁content: 您的验证码是{}。请不要把验证码泄露给其他人。.format(get_code()),# 没有购买套餐的这个模板只能使用默认的即你收到的短信长这样【互亿无线】您的验证码是7835。请不要把验证码泄露给其他人。format: json, # 不要动}# 将数据进行编码下面代码不要动data urllib.parse.urlencode(values).encode(encodingUTF8)# 发起请求下面代码不要动req urllib.request.Request(url, data)response urllib.request.urlopen(req)res response.read()# 打印结果然后你的手机应该就能接到短信了print(res.decode(utf8), type(res.decode(utf8))) # {code:2,msg:提交成功,smsid:16842079209571524017}dict_res json.loads(res.decode(utf8))if dict_res.get(code, 0) 2:print(短信发送成功请留意手机)return Trueelse:print(发送失败)return False{code:2,msg:提交成功,smsid:16906979568648248914} class str短信发送成功请留意手机# 短信长这样【互亿无线】您的验证码是3476。请不要把验证码泄露给其他人。if __name__ __main__:send_sms(18211101742)响应结果的状态码查询https://www.ihuyi.com/api/sms.html 小结 如果腾讯云能通过签名认证则首选腾讯云短信。想发谁就发谁可以自定义短信模板和签名。其次是云通信短信。测试开发阶段可以不认证就可以进行测试但模板和签名都是默认的而且收短信的手机号必须是在平台注册的。而且它免费赠送了一些短信额度比较划算。最后备选是互亿无限它发短信稍微慢了点。有十条免费的短信重置也不贵10块钱200条。 Django4中的日志管理 参考Django配置日志https://www.cnblogs.com/Neeo/articles/17588553.html python内置模块logging模块https://www.cnblogs.com/Neeo/articles/10951734.html 按照文件大小进行切割日志 在你的settings.py中。 LOGS_DIRS os.path.join(BASE_DIR, logs) if not os.path.exists(LOGS_DIRS):os.makedirs(LOGS_DIRS)# 日志 LOGGING {version: 1, # 使用的日志模块的版本目前官方提供的只有版本1但是官方有可能会升级为了避免升级出现的版本问题所以这里固定为1disable_existing_loggers: False, # 是否禁用其他的已经存在的日志功能肯定不能有可能有些第三方模块在调用所以禁用了以后第三方模块无法捕获自身出现的异常了。formatters: { # 日志格式设置verbose或者simple都是自定义的verbose: { # 详细格式适合用于开发人员不在场的情况下的日志记录。# 格式定义https://docs.python.org/3/library/logging.html#logrecord-attributes# levelname 日志等级# asctime 发生时间# module 文件名# process 进程ID# thread 线程ID# message 异常信息format: {levelname} {asctime} {module} {process:d} {thread:d} {message},style: {, # 变量格式分隔符},simple: { # 简单格式适合用于开发人员在场的情况下的终端输出format: {levelname} {message},style: {,},},filters: { # 过滤器require_debug_true: {(): django.utils.log.RequireDebugTrue,},},handlers: { # 日志处理流程console或者mail_admins都是自定义的。console: {level: DEBUG, # 设置当前日志处理流程中的日志最低等级filters: [require_debug_true], # 当前日志处理流程的日志过滤class: logging.StreamHandler, # 当前日志处理流程的核心类StreamHandler可以帮我们把日志信息输出到终端下formatter: simple # 当前日志处理流程的日志格式},# mail_admins: {# level: ERROR, # 设置当前日志处理流程中的日志最低等级# class: django.utils.log.AdminEmailHandler, # AdminEmailHandler可以帮我们把日志信息输出到管理员邮箱中。# filters: [special] # 当前日志处理流程的日志过滤# }file: {level: INFO,class: logging.handlers.RotatingFileHandler,# 日志位置,日志文件名日志保存目录logs必须手动创建filename: %s/django.log % LOGS_DIRS,# 单个日志文件的最大值这里我们设置300MmaxBytes: 300 * 1024 * 1024,# 备份日志文件的数量设置最大日志数量为10backupCount: 10,# 日志格式:详细格式formatter: verbose,encoding: utf-8, # 输出日志编码},},loggers: { # 日志处理的命名空间django: {handlers: [console, file], # 当基于django命名空间写入日志时调用那几个日志处理流程propagate: True, # 是否在django命名空间对应的日志处理流程结束以后冒泡通知其他的日志功能。True表示允许},} } 遇到切割文件时遇到权限报错的解决方案Windows为例。 下载模块pip install concurrent-log-handler 在原有的配置项中修改 # 决定日志保存到哪个文件夹下我这里将自动创建到项目根目录下的logs文件夹内 LOGS_DIRS os.path.join(BASE_DIR, logs) if not os.path.exists(LOGS_DIRS):os.makedirs(LOGS_DIRS)# 按照文件大小进行切割日志 LOGGING {version: 1, # 使用的日志模块的版本目前官方提供的只有版本1但是官方有可能会升级为了避免升级出现的版本问题所以这里固定为1disable_existing_loggers: False, # 是否禁用其他的已经存在的日志功能肯定不能有可能有些第三方模块在调用所以禁用了以后第三方模块无法捕获自身出现的异常了。formatters: { # 日志格式设置verbose或者simple都是自定义的verbose: { # 详细格式适合用于开发人员不在场的情况下的日志记录。# 格式定义https://docs.python.org/3/library/logging.html#logrecord-attributes# levelname 日志等级# asctime 发生时间# module 文件名# process 进程ID# thread 线程ID# message 异常信息format: {levelname} {asctime} {module} {process:d} {thread:d} {message},style: {, # 变量格式分隔符},simple: { # 简单格式适合用于开发人员在场的情况下的终端输出format: {levelname} {message},style: {,},},filters: { # 过滤器require_debug_true: {(): django.utils.log.RequireDebugTrue,},},handlers: { # 日志处理流程console或者mail_admins都是自定义的。console: {level: DEBUG, # 设置当前日志处理流程中的日志最低等级filters: [require_debug_true], # 当前日志处理流程的日志过滤class: logging.StreamHandler, # 当前日志处理流程的核心类StreamHandler可以帮我们把日志信息输出到终端下formatter: simple # 当前日志处理流程的日志格式},# mail_admins: {# level: ERROR, # 设置当前日志处理流程中的日志最低等级# class: django.utils.log.AdminEmailHandler, # AdminEmailHandler可以帮我们把日志信息输出到管理员邮箱中。# filters: [special] # 当前日志处理流程的日志过滤# }file: {level: INFO,# class: logging.handlers.RotatingFileHandler, # 默认的按照文件大小切割日志class: concurrent_log_handler.ConcurrentRotatingFileHandler, # Windows下安装并使用 concurrent-log-handler# class: cloghandler.ConcurrentRotatingFileHandler, # Linux安装并使用 ConcurrentLogHandlerdelay: True, # 同时添加delay参数# 日志位置,日志文件名日志保存目录logs必须手动创建filename: %s/django.log % LOGS_DIRS,# 单个日志文件的最大值这里我们设置300M# maxBytes: 300 * 1024 * 1024,maxBytes: 0.1 * 1024 * 1024,# 备份日志文件的数量设置最大日志数量为10backupCount: 10,# 日志格式:详细格式formatter: verbose,encoding: utf-8, # 输出日志编码},},loggers: { # 日志处理的命名空间django: {handlers: [console, file], # 当基于django命名空间写入日志时调用那几个日志处理流程propagate: True, # 是否在django命名空间对应的日志处理流程结束以后冒泡通知其他的日志功能。True表示允许},} } 按照时间进行切割日志 在你的settings.py中。 LOGS_DIRS os.path.join(BASE_DIR, logs) if not os.path.exists(LOGS_DIRS):os.makedirs(LOGS_DIRS)# 日志 LOGGING {version: 1, # 使用的日志模块的版本目前官方提供的只有版本1但是官方有可能会升级为了避免升级出现的版本问题所以这里固定为1disable_existing_loggers: False, # 是否禁用其他的已经存在的日志功能肯定不能有可能有些第三方模块在调用所以禁用了以后第三方模块无法捕获自身出现的异常了。formatters: { # 日志格式设置verbose或者simple都是自定义的verbose: { # 详细格式适合用于开发人员不在场的情况下的日志记录。# 格式定义https://docs.python.org/3/library/logging.html#logrecord-attributes# levelname 日志等级# asctime 发生时间# module 文件名# process 进程ID# thread 线程ID# message 异常信息format: {levelname} {asctime} {module} {process:d} {thread:d} {message},style: {, # 变量格式分隔符},simple: { # 简单格式适合用于开发人员在场的情况下的终端输出format: {levelname} {message},style: {,},},filters: { # 过滤器require_debug_true: {(): django.utils.log.RequireDebugTrue,},},handlers: { # 日志处理流程console或者mail_admins都是自定义的。console: {level: DEBUG, # 设置当前日志处理流程中的日志最低等级filters: [require_debug_true], # 当前日志处理流程的日志过滤class: logging.StreamHandler, # 当前日志处理流程的核心类StreamHandler可以帮我们把日志信息输出到终端下formatter: simple # 当前日志处理流程的日志格式},# mail_admins: {# level: ERROR, # 设置当前日志处理流程中的日志最低等级# class: django.utils.log.AdminEmailHandler, # AdminEmailHandler可以帮我们把日志信息输出到管理员邮箱中。# filters: [special] # 当前日志处理流程的日志过滤# }file: {level: INFO,class: logging.handlers.TimedRotatingFileHandler,# 日志位置,日志文件名日志保存目录logs必须手动创建filename: %s/django.log % LOGS_DIRS,# TimedRotatingFileHandler的参数# 目前设定每天一个日志文件# S | 秒# M | 分# H | 时# D | 天# W0-W6 | 周一至周日# midnight | 每天的凌晨when: S, # 间间隔的类型指定秒就不要在Windows上运行测试interval: 5, # 时间间隔backupCount: 5, # 能留几个日志文件;过数量就会丢弃掉老的日志文件encoding: utf-8, # 日志文本编码},},loggers: { # 日志处理的命名空间django: {handlers: [console, file], # 当基于django命名空间写入日志时调用那几个日志处理流程propagate: True, # 是否在django命名空间对应的日志处理流程结束以后冒泡通知其他的日志功能。True表示允许},} }如果在Windows上按照日期进行切割报错建议不要在Windows上用按照时间进行切割的方式使用日志请按照文件大小进行切割的方式用就行了。另外默认的按照日期进行切割的配置只在Windows上报错在Linux上不报错。 最终建议无论是Windows还是Linux如果不想报错就都用按照文件大小进行切割就行了。 单独使用logger怎么做 你可以这样搞在项目某个路径下创建一个日志的配置文件比如我将它创建在项目根目录下的utils/logger.py中填写代码 import logging.config from django.conf import settingslogger logging.getLogger(django) logging.config.dictConfig(settings.LOGGING) # logging配置然后在你需要的地方引入logger对象就行了 import datetime from django.shortcuts import render, HttpResponse from utils.logger import logger def index(request):now datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S)logger.info(info.....)logger.warning(warning.....)logger.error(error.....)return HttpResponse(now)Django4中的信号 参考https://www.cnblogs.com/Neeo/articles/17589746.html 内置信号的基本写法在你的项目同名文件夹下的__init__.py # 导入相关信号 from django.core.signals import request_started, request_finished # 以装饰器的形式激活信号所以要先导入装饰器 from django.dispatch import receiverreceiver(request_started) def my_callback(sender, **kwargs): 回调函数 print(my_callback, sender)插入基本的orm用法 参考这个https://www.cnblogs.com/Neeo/articles/10967645.html#orm%E7%AE%80%E4%BB%8B 代码就是models.py: from django.db import modelsclass User(models.Model):name models.CharField(max_length32, verbose_name姓名)def __str__(self):return self.namesettings.py DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: day07, #你的数据库名称USER: root, #你的数据库用户名PASSWORD: 123, #你的数据库密码HOST: , #你的数据库主机留空默认为localhostPORT: 3306, #你的数据库端口} }# orm语句转为具体SQL的语句配置你们可以自己在笔记中记录一下 LOGGING {version: 1,disable_existing_loggers: False,handlers: {console:{level:DEBUG,class:logging.StreamHandler,},},loggers: {django.db.backends: {handlers: [console],propagate: True,level:DEBUG,},} }注意别忘了在根目录下打开terminal执行下面两个命令 python manage.py makemigrations python manage.py migrateurls.py from django.contrib import admin from django.urls import path from api import viewsurlpatterns [path(admin/, admin.site.urls),path(index/, views.index), ]views.py: from django.shortcuts import render, HttpResponse from api.models import Userdef index(request):# 创建命令# obj User.objects.create(namezhangkai)# print(obj)# 更新方式1# obj User.objects.filter(namezhangkai1).first()# obj.name zhangkai2# print(obj)# obj.save()# 更新方式2# User.objects.filter(namezhangkai).update(namezhangkai3)# 删除# User.objects.filter(namezhangkai3).delete()# 查询User.objects.filter(namezhangkai3) # 根据条件查询 相当于select * from api_user where namezhangaki;User.objects.all() # 查所有相当于select * from api_user;return HttpResponse(INDEX)内置信号的用法示例 新增模型类对象触发的相关信号 views.py: from django.shortcuts import render, HttpResponse from api.models import User# ----------- 内置信号的用法 -------------- def index(request):# 什么时候模型类对象调用save方法答案是创建对象的时候和更新对象的时候obj User.objects.create(namezhangkai)print(obj)return HttpResponse(INDEX)demo/__init__.py from django.db.models.signals import pre_init, post_init, pre_save, post_save, pre_delete, post_delete from django.dispatch import receiverreceiver(pre_init) def pre_init_callback(sender, **kwargs): 每当实例化一个 Django 模型时这个信号都会在模型的 __init__() 方法的开头发出 print(pre_init_callback, sender)print(pre_init_callback, kwargs)receiver(post_init) def post_init_callback(sender, **kwargs): 和 pre_init 一样但这个是在 __init__() 方法完成后发送的 print(post_init_callback, sender)print(post_init_callback, kwargs)receiver(pre_save) def pre_save_callback(sender, **kwargs): 这是在模型的 save() 方法开始时发送的 print(pre_save_callback, sender)print(pre_save_callback, kwargs)print(pre_save_callback, kwargs[instance].name)receiver(post_save) def post_save_callback(sender, **kwargs): 就像 pre_save 一样但在 save() 方法的最后发送 print(post_save_callback, sender)print(post_save_callback, kwargs)print(post_save_callback, kwargs[instance].name)以及打印效果 pre_init_callback class api.models.User pre_init_callback {signal: django.db.models.signals.ModelSignal object at 0x00000159F5287DC0, args: (), kwargs: {name: zhangkai}} post_init_callback class api.models.User post_init_callback {signal: django.db.models.signals.ModelSignal object at 0x00000159F5287EE0, instance: User: zhangkai} pre_save_callback class api.models.User pre_save_callback {signal: django.db.models.signals.ModelSignal object at 0x00000159F5287FD0, instance: User: zhangkai, raw: False, using: default, update_fields: None} pre_save_callback zhangkai post_save_callback class api.models.User post_save_callback {signal: django.db.models.signals.ModelSignal object at 0x00000159F52C4100, instance: User: zhangkai, created: True, update_fields: None, raw: False, using: default} post_save_callback zhangkai zhangkai编辑模型类对象触发的相关信号 views.py: from django.shortcuts import render, HttpResponse from api.models import User# ----------- 内置信号的用法 -------------- def index(request):# 什么时候模型类对象调用save方法答案是创建对象的时候和更新对象的时候# 新增# obj User.objects.create(namezhangkai)# print(obj)# 编辑obj User.objects.filter(namezhangkai2).first()old obj.nameobj.name zhangkai888new obj.name# log.info(f{old}--{new})obj.save()return HttpResponse(INDEX)demo/__init__.py from django.db.models.signals import pre_init, post_init, pre_save, post_save, pre_delete, post_delete from django.dispatch import receiverreceiver(pre_init) def pre_init_callback(sender, **kwargs): 每当实例化一个 Django 模型时这个信号都会在模型的 __init__() 方法的开头发出 print(pre_init_callback, sender)print(pre_init_callback, kwargs)receiver(post_init) def post_init_callback(sender, **kwargs): 和 pre_init 一样但这个是在 __init__() 方法完成后发送的 print(post_init_callback, sender)print(post_init_callback, kwargs)receiver(pre_save) def pre_save_callback(sender, **kwargs): 这是在模型的 save() 方法开始时发送的 print(pre_save_callback, sender)print(pre_save_callback, kwargs)print(pre_save_callback, kwargs[instance].name)receiver(post_save) def post_save_callback(sender, **kwargs): 就像 pre_save 一样但在 save() 方法的最后发送 print(post_save_callback, sender)print(post_save_callback, kwargs)print(post_save_callback, kwargs[instance].name)日志 pre_init_callback class api.models.User pre_init_callback {signal: django.db.models.signals.ModelSignal object at 0x00000186F4937DC0, args: (1, zhangkai2), kwargs: {}} post_init_callback class api.models.User post_init_callback {signal: django.db.models.signals.ModelSignal object at 0x00000186F4937EE0, instance: User: zhangkai2} zhangkai2 pre_save_callback class api.models.User pre_save_callback {signal: django.db.models.signals.ModelSignal object at 0x00000186F4937FD0, instance: User: zhangkai888, raw: False, using: default, update_fields: None} pre_save_callback zhangkai888 post_save_callback class api.models.User post_save_callback {signal: django.db.models.signals.ModelSignal object at 0x00000186F4974100, instance: User: zhangkai888, created: False, update_fields: None, raw: False, using: default} post_save_callback zhangkai888删除模型类对象触发的相关信号 views.py: from django.shortcuts import render, HttpResponse from api.models import User# ----------- 内置信号的用法 --------------def index(request):# 什么时候模型类对象调用save方法答案是创建对象的时候和更新对象的时候# 新增# obj User.objects.create(namezhangkai)# print(obj)# 编辑# obj User.objects.filter(namezhangkai2).first()# old obj.name# obj.name zhangkai888# new obj.name# # log.info(f{old}--{new})# obj.save()# 删除obj_list User.objects.filter(namezhangkai888)# print(111, obj_list) # QuerySet [User: zhangkai888, User: zhangkai888, User: zhangkai888]for obj in obj_list:obj.delete()return HttpResponse(INDEX)demo/__init__.py from django.db.models.signals import pre_init, post_init, pre_save, post_save, pre_delete, post_delete from django.dispatch import receiverreceiver(pre_init) def pre_init_callback(sender, **kwargs): 每当实例化一个 Django 模型时这个信号都会在模型的 __init__() 方法的开头发出 print(pre_init_callback, sender)print(pre_init_callback, kwargs)receiver(post_init) def post_init_callback(sender, **kwargs): 和 pre_init 一样但这个是在 __init__() 方法完成后发送的 print(post_init_callback, sender)print(post_init_callback, kwargs)receiver(pre_save) def pre_save_callback(sender, **kwargs): 这是在模型的 save() 方法开始时发送的 print(pre_save_callback, sender)print(pre_save_callback, kwargs)print(pre_save_callback, kwargs[instance].name)receiver(post_save) def post_save_callback(sender, **kwargs): 就像 pre_save 一样但在 save() 方法的最后发送 print(post_save_callback, sender)print(post_save_callback, kwargs)print(post_save_callback, kwargs[instance].name)receiver(pre_delete) def pre_delete_callback(sender, **kwargs): 在模型的 delete() 方法和查询集的 delete() 方法开始时发送 print(pre_delete_callback, sender)print(pre_delete_callback, kwargs)receiver(post_delete) def post_delete_callback(sender, **kwargs): 就像 pre_delete 一样但在模型的 delete() 方法和查询集的 delete() 方法结束时发送 print(post_delete_callback, sender)print(post_delete_callback, kwargs)日志 post_init_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD6FE7EE0, instance: User: zhangkai888} pre_delete_callback class api.models.User pre_delete_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD70241F0, instance: User: zhangkai888, using: default, origin: User: zhangkai888} post_delete_callback class api.models.User post_delete_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD70242E0, instance: User: zhangkai888, using: default, origin: User: zhangkai888} pre_delete_callback class api.models.User pre_delete_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD70241F0, instance: User: zhangkai888, using: default, origin: User: zhangkai888} post_delete_callback class api.models.User post_delete_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD70242E0, instance: User: zhangkai888, using: default, origin: User: zhangkai888} pre_delete_callback class api.models.User pre_delete_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD70241F0, instance: User: zhangkai888, using: default, origin: User: zhangkai888} post_delete_callback class api.models.User post_delete_callback {signal: django.db.models.signals.ModelSignal object at 0x0000026FD70242E0, instance: User: zhangkai888, using: default, origin: User: zhangkai888}Django4中的缓存 详细文档参考https://www.cnblogs.com/Neeo/articles/17589834.html Django支持的缓存有好几种 三方的Redis(推荐)Memcached(不推荐)缓存到本地文件缓存到本地数据库缓存到内存里虚拟缓存 缓存的粒度 局部视图缓存 缓存指定的视图函数有两种写法. 在视图中以装饰器的形式 views.py import datetime from django.shortcuts import render, HttpResponse# 必须导入缓存装饰器 from django.views.decorators.cache import cache_pagecache_page(5) # 缓存单位秒 def index(request):# print(1111)now datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S)return render(request, index.html, {now: now})urls.py: from django.contrib import admin from django.urls import path from api import viewsurlpatterns [path(admin/, admin.site.urls),path(index/, views.index), ]在路由中实现 views.py import datetime from django.shortcuts import render, HttpResponsedef index(request):# print(1111)now datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S)return render(request, index.html, {now: now})urls.py from django.contrib import admin from django.urls import path from api import viewsfrom django.views.decorators.cache import cache_page urlpatterns [path(admin/, admin.site.urls),# path(index/, views.index),path(index/, cache_page(5)(views.index)), # 缓存路由中指定缓存的视图函数 ]模板缓存粒度更新相当于对于页面的局部进行缓存 views.py中正常写代码 import datetime from django.shortcuts import render, HttpResponse # 必须导入缓存装饰器 # from django.views.decorators.cache import cache_page # # # cache_page(5) # 缓存单位秒 def index(request):# print(1111)now datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S)return render(request, index.html, {now: now}) urls.py正常写代码 from django.contrib import admin from django.urls import path from api import views# from django.views.decorators.cache import cache_page urlpatterns [path(admin/, admin.site.urls),path(index/, views.index),# path(index/, cache_page(5)(views.index)), # 缓存路由中指定缓存的视图函数 ]index.html这里就需要注意了。 必须load cache必须用缓存的模板把要缓存的内容包起来才能被缓存上其它没包裹的标签不缓存。 {% load cache %} !-- 必须声明 -- !DOCTYPE html html langen headmeta charsetUTF-8titleTitle/title /head body h3没有缓存的/h3 p{{ now }}/ph3有缓存的/h3 !-- cache 后面的5表示缓存的时间5后面的字符串来自于settings.py中的缓存配置中的LOCATION的值unique-snowflake-- !-- 用缓存的模板把要缓存的内容包起来-- {% cache 5 unique-snowflake %}p{{ now }}/pp{{ now }}/p {% endcache %} /body /html全栈缓存 就是整个项目进行缓存粒度是最大的。 首先要配置settings.py MIDDLEWARE [# 下面这个缓存中间件必须放在所有中间件的最上面django.middleware.cache.UpdateCacheMiddleware,django.middleware.security.SecurityMiddleware,django.contrib.sessions.middleware.SessionMiddleware,django.middleware.common.CommonMiddleware,django.middleware.csrf.CsrfViewMiddleware,django.contrib.auth.middleware.AuthenticationMiddleware,django.contrib.messages.middleware.MessageMiddleware,django.middleware.clickjacking.XFrameOptionsMiddleware,# 下面这个缓存中间件必须放在所有中间件的最下面django.middleware.cache.FetchFromCacheMiddleware, ]# 我这里将cache缓存由本地内存缓存更换为了Redis CACHES {default: {BACKEND: django_redis.cache.RedisCache,LOCATION: redis://:127.0.0.1:6379/2,OPTIONS: {CLIENT_CLASS: django_redis.client.DefaultClient,PASSWORD: 1234, # 密码如果没有设置密码这个参数可以注视掉# MAX_ENTRIES: 300, # 最大缓存个数默认300# CULL_FREQUENCY: 3, # 缓存到达最大个数之后剔除缓存个数的比例即1/CULL_FREQUENCY默认3}} }# 默认超时时间是300秒我们可以通过CACHE_MIDDLEWARE_SECONDS来修改 CACHE_MIDDLEWARE_SECONDS 20 # 下面是关于key的咱们这里保持默认就完了 CACHE_MIDDLEWARE_KEY_PREFIX # 用于存储的缓存别名没想好的指定个default就行 CACHE_MIDDLEWARE_ALIAS defaultviews.py正常写代码 import datetime from django.shortcuts import render, HttpResponse # 必须导入缓存装饰器 # from django.views.decorators.cache import cache_page # # # cache_page(5) # 缓存单位秒 def index(request):# print(1111)now datetime.datetime.now().strftime(%Y-%m-%d %H:%M:%S)return render(request, index.html, {now: now}) urls.py正常写代码 from django.contrib import admin from django.urls import path from api import views# from django.views.decorators.cache import cache_page urlpatterns [path(admin/, admin.site.urls),path(index/, views.index),# path(index/, cache_page(5)(views.index)), # 缓存路由中指定缓存的视图函数 ]index.html也正常写代码 {% load cache %} !-- 必须声明 -- !DOCTYPE html html langen headmeta charsetUTF-8titleTitle/title /head body h3没有缓存的/h3 p{{ now }}/ph3有缓存的/h3 {% cache 5 unique-snowflake %}p{{ now }}/pp{{ now }}/p {% endcache %}/body /html注意如果同时使用了全栈缓存和局部模板片段缓存那么全栈缓存的优先级高。 Redis 数据库排行榜https://db-engines.com/en/ranking redis是一个独立的非关系型数据。 官方建议将Redis安装到Linux系统所以你在redis官网压根看不到redis关于Windows的安装包。 redis3 for Windows 参考https://www.cnblogs.com/Neeo/articles/12673194.html#windows 和讲解视频 redis3 for centos 参考https://www.cnblogs.com/Neeo/articles/12673194.html#redis307-for-centos79 和讲解视频 注意必须关闭你的centos系统的防火墙 # 查看防火墙状态 systemctl status firewalld.service # 关闭防火墙 systemctl stop firewalld.service # 禁止开机启动防火墙 systemctl disable firewalld.service # 启动防火墙 systemctl start firewalld.service # 防火墙随系统开启启动 systemctl enable firewalld.service# 关闭selinux [rootr ~]# sed -i.ori s#SELINUXenforcing#SELINUXdisabled#g /etc/selinux/config关于Redis使用和python如何操作 参考我的博客https://www.cnblogs.com/Neeo/p/10864123.html#database 关于Django如何操作Redis参考https://www.cnblogs.com/Neeo/articles/14269422.html
http://www.zqtcl.cn/news/910930/

相关文章:

  • 桂林微信网站wordpress 连接信息
  • 电商网站开发简历跨境电商怎么搞
  • php小型网站开发百度知道小程序
  • 风铃网站具体是做那方面的contact form7 v2.1.2 wordpress
  • 临沂网站建设举措网站数据不变重新安装wordpress
  • 外贸网站建设双语网站建设红色大气网络公司企业网站源码_适合广告设计
  • 温州哪里有做网站的阳朔到桂林机场
  • 商务网站建设详细流程小程序商城服务好的商家
  • 苏州建站模板搭建南京地铁最新消息
  • wordpress建网站教程威海建设招聘信息网站
  • 如何制作一网站企业中标信息查询网
  • 百度推广咨询seo搜索引擎优化平台
  • 建设网站要不要投资钱哪里建设网站最好
  • 长沙网站制作公司地址农业推广作业
  • 网站创意设计公司定制网站开发价格
  • 专业网站建设加盟合作怀化seo快速排名
  • 房山区网站建设wordpress自动采集翻译插件怎么用
  • 郴州做网站 郴网互联网站制作公司起名
  • 织梦做的的网站首页显示空白查企业营业执照的网站
  • 葫芦岛公司做网站外贸西班牙语网站建设
  • 广西住房和城乡建设厅培训中心网站首页wordpress建导航
  • 企业建立网站需要提供什么建立网站需要多长钱
  • 科技企业网站源码下载网页设计公司哪家效果好
  • 成都龙泉工程建设有限公司网站网络科技有限公司网站建设策划书
  • 温州网站建设对比赣州招聘网最新招聘
  • 网站建设什么时候好商丘创小资网络有限公司
  • 做网站不切片可以吗wordpress导入表单
  • 广告公司的网站建设价格wordpress简洁淘宝客免费主题
  • 内蒙古建设安全监督站的网站做网站排名多少钱
  • 自学网站平面设计友链大全