python学习笔记

深拷贝和浅拷贝

import copy
# 深拷贝会创建一个新的对象,属性的独立出来的,之前所复制的属性做出了修改不会被影响
#浅拷贝会创建一个新的对象,对应的属性会跟之前的对象做属性的共享,当之前的属性受到影响做出修改后,新的对象的属性也会受到影响
# 定义一个嵌套对象
obj = {'name': 'Alice', 'age': 25, 'address': {'city': 'New York'}}
# 创建浅拷贝对象
obj_copy = copy.copy(obj)
# 创建深拷贝对象
obj_deep_copy = copy.deepcopy(obj)
obj_deep_copy1 = copy.copy(obj)
obj['address']['city'] = 'London'
print(obj) # {'name': 'Alice', 'age': 25, 'address': {'city': 'London'}}
print("深拷贝"+str(obj_deep_copy)) # {'name': 'Alice', 'age': 25, 'address': {'city': 'New York'}}
print("浅拷贝"+str(obj_deep_copy1))

Pytest

import sys
import pytest
def inc(x):
return x+1
def test_answer():
assert inc(4) == 5
def test_str():
assert "a" in "abc"
def test_print():
print(sys.platform)
assert True
params = ["appnium","pytest","selenium"]
@pytest.mark.parametrize("param",[
("3+5",8),("2+5",7),("7+5",12)
])
@pytest.mark.parametrize("expected",params)
def test_mark_more(param,expected):
print(f"param:{param},expected:{expected}")
# mark标签用来对测试用例做标记,可以通过标记来做对应的测试用例调用
# pytest -vs -m "mark标签名"
@pytest.mark.add
def test_function_add():
print("test number add function")
assert 1+5 == 6
@pytest.mark.sub
def test_function_sub():
print("test number sub function")
assert 1-5 == -4
@pytest.mark.mult
def test_function_mult():
print("test number mult function")
assert 1*5 == 5
@pytest.mark.divide
def test_function_divide():
print("test number divide function")
assert 1/5 == 0.2
@pytest.mark.divide
def test_function_divide2():
print("test number divide function")
assert 1/10 == 0.1

如果希望没有警告,在项目根目录下创建pytest.ini文件,并输入对应的内容

[pytest]
markers = add
sub
mult
divide
parametrize
# 跳过这条用例
@pytest.mark.skip
def test_print():
print("test)
# 跳过这条用例并返回原因
@pytest.mark.skip(reason="原因")
def test_print1():
print("test)
# 如果满足条件,就跳过这条用例
@pytest.mark.skipif(sys.platform="win",reason="do not run in windows")
def test_print3():
print("test)
# xfail预期运行失败能够符合预期
@pytest.mark.xfail(reason="原因")
def test_print4():
print("代码尚未开发完")

pytest test_demo.py -vs --lf
--lf参数:将所有失败的测试用例全部重新执行一次
pytest test_demo.py -vs --ff
--ff参数:先执行所有失败的测试用例,再去执行其他的测试用例
-x参数:用例一旦失败(fail/error),就立刻停止执行
--maxfail=num参数:用例达到num数量
-m参数:运行被标记的标签的用例
-k参数:执行包含某个关键字的测试用例
-v参数:打印详细日志
-s参数:打印输出日志(一般-vs一起使用)
-collect-only(测试平台,pytest 自动导入功能)

def test_raise1():
with pytest.raises(ZeroDivisionError) as exc_info:
raise ValueError("value must be 42")
# 获取异常并抛出进行断言
assert exc_info.type is ValueError
assert exc_info.value.args[0] == "value must be 42"

数据驱动-yaml

selenium高级交互

鼠标滚轮操作

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
class TestScroll:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
def teardown_class(self):
self.driver.quit()
def test_scroll(self):
# 滚动到对应元素的位置
self.driver.get("https://ceshiren.com/tag/%E7%B2%BE%E5%8D%8E%E5%B8%96")
self.driver.maximize_window()
ele1 = self.driver.find_element(By.XPATH,"//*[text()='毕业设计-针对OB-制品项目业务测试方案']")
ActionChains(self.driver).scroll_to_element(ele1).perform()
time.sleep(15)
def test_scroll_to_xy(self):
# 滚动到对应坐标的位置
self.driver.get("https://ceshiren.com/tag/%E7%B2%BE%E5%8D%8E%E5%B8%96")
self.driver.maximize_window()
ActionChains(self.driver).scroll_by_amount(0,3000).perform()
time.sleep(10)

鼠标移动操作

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
class TestMouse:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
def teardown_class(self):
self.driver.quit()
def test_double_click(self):
# 鼠标双击操作
self.driver.get("https://vip.ceshiren.com/#/ui_study/frame")
self.driver.maximize_window()
ele = self.driver.find_element(By.ID,"primary_btn")
ActionChains(self.driver).double_click(ele).perform()
time.sleep(5)
def test_drag_and_drop(self):
# 鼠标拖动操作
self.driver.get("https://vip.ceshiren.com/#/ui_study/action_chains")
self.driver.maximize_window()
ele1 = self.driver.find_element(By.ID,"item1")
ele2 = self.driver.find_element(By.ID,"item3")
ActionChains(self.driver).drag_and_drop(ele1, ele2).perform()
time.sleep(5)
def test_move_to_element(self):
# 鼠标悬浮操作
self.driver.get("https://vip.ceshiren.com/#/ui_study/action_chains2")
self.driver.maximize_window()
ele1 = self.driver.find_element(By.CLASS_NAME,"title")
ele2 = self.driver.find_element(By.XPATH,"//*[contains(text(),'管理班')]")
ActionChains(self.driver)\
.move_to_element(ele1)\
.click(ele2)\
.perform()
time.sleep(5)

键盘输入操作

import sys
import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
class Testweb:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
def teardown_class(self):
self.driver.quit()
def test_shife(self):
# 键盘输入带shift按键
self.driver.get("https://ceshiren.com")
self.driver.maximize_window()
self.driver.find_element(By.ID,"search-button").click()
ele = self.driver.find_element(By.ID,"search-term")
ActionChains(self.driver).key_down(Keys.SHIFT, ele).send_keys("selenium").perform()
time.sleep(5)
def test_enter_by_send_keys(self):
# 键盘输入指定内容
self.driver.get("https://www.sogou.com/")
self.driver.maximize_window()
self.driver.find_element(By.ID,"query").send_keys("selenium")
self.driver.find_element(By.ID,"stb").click()
time.sleep(5)
def test_exit_by_actions(self):
# 键盘输入指定内容并按回车进行搜索
self.driver.get("https://www.sogou.com/")
self.driver.maximize_window()
ActionChains(self.driver)\
.key_down(Keys.SHIFT)\
.send_keys("selenium")\
.key_down(Keys.ENTER)\
.perform()
time.sleep(5)
def test_copy_and_paste(self):
# 键盘进行copy和paste操作
self.driver.get("https://www.sogou.com/")
self.driver.maximize_window()
if sys.platform == "darwin":
command_control = Keys.COMMAND
else:
command_control = Keys.CONTROL
ele = self.driver.find_element(By.ID,"query")
ActionChains(self.driver)\
.key_down(Keys.SHIFT,ele)\
.send_keys("selenium")\
.key_down(Keys.ARROW_LEFT)\
.key_down(command_control)\
.send_keys("cvvvv").key_up(command_control).perform()
time.sleep(5)

多窗口和frame处理

切换页面和切换frame

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
class TestBaidu:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
self.driver.maximize_window()
def tear_down(self):
self.driver.quit()
def test_baidu(self):
# 切换页面
self.driver.get("https://www.baidu.com/")
self.driver.find_element(By.LINK_TEXT, "登录").click()
# print(self.driver.current_window_handle)
self.driver.find_element(By.LINK_TEXT, "立即注册").click()
windows = self.driver.window_handles
self.driver.switch_to.window(windows[1])
self.driver.find_element(By.ID,"TANGRAM__PSP_4__userName").send_keys("username")
self.driver.find_element(By.ID,"TANGRAM__PSP_4__phone").send_keys("15915420233")
self.driver.find_element(By.ID,"TANGRAM__PSP_4__password").send_keys("password")
self.driver.switch_to.window(windows[0])
self.driver.find_element(By.ID, "TANGRAM__PSP_11__userName").send_keys("username")
self.driver.find_element(By.ID, "TANGRAM__PSP_11__password").send_keys("password")
time.sleep(5)
def test_switch_to_frame(self):
# 切换frame后切换回默认frame
self.driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
self.driver.switch_to.frame("iframeResult")
print(self.driver.find_element(By.ID, "draggable").text)
self.driver.switch_to.parent_frame()
print(self.driver.find_element(By.ID, "submitBTN").text)
# time.sleep(5)

文件上传及弹窗处理

上传文件

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestIamge:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
self.driver.maximize_window()
def teardown_class(self):
self.driver.quit()
def test_uploadfile(self):
# 文件上传
self.driver.get("https://image.baidu.com/")
self.driver.find_element(By.XPATH,"//*[@id='sttb']/img[1]").click()
self.driver.find_element(By.ID,"stfile").send_keys("D:\code_repository\pythonProject\img\img1.jpg")
time.sleep(5)

弹窗处理

import time
from selenium import webdriver
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
class TestAlert:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
self.driver.maximize_window()
def teardown_class(self):
self.driver.quit()
def test_alert(self):
# 弹窗处理
self.driver.get("https://www.runoob.com/try/try.php?filename=jqueryui-api-droppable")
self.driver.switch_to.frame("iframeResult")
element = self.driver.find_element(By.ID, "draggable")
target_element = self.driver.find_element(By.ID, "droppable")
ActionChains(self.driver).drag_and_drop(element,target_element).perform()
alert = self.driver.switch_to.alert
print(alert.text)
alert.accept()
time.sleep(5)

获取日志

日志工具类

import logging
# 创建logger实例
logger = logging.getLogger('simple_example')
# 设置日志级别
logger.setLevel(logging.DEBUG)
# 流处理器
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
# 日志打印格式
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
# 添加格式配置
ch.setFormatter(formatter)
# 添加日志配置
logger.addHandler(ch)

打印日志和截图、获取源码

import time
from selenium import webdriver
from selenium.webdriver.common.by import By
from log_util import logger
class TestDataRecord:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.implicitly_wait(3)
self.driver.maximize_window()
def teardown_class(self):
self.driver.quit()
def test_log_data_record(self):
# 打印日志
search_content = "selenium"
self.driver.get("https://www.sogou.com/")
self.driver.find_element(By.ID, "query").send_keys(search_content)
logger.debug(f"搜索信息为{search_content}")
self.driver.find_element(By.ID, "stb").click()
elements = self.driver.find_elements(By.CSS_SELECTOR, 'em')
for element in elements:
logger.info(f"实际结果为{element.text},预期结果为{search_content}")
time.sleep(5)
def test_screenshot_data_record(self):
# 保存截图
search_content = "selenium"
self.driver.get("https://www.sogou.com/")
self.driver.find_element(By.ID, "query").send_keys(search_content)
logger.debug(f"搜索信息为{search_content}")
self.driver.find_element(By.ID, "stb").click()
elements = self.driver.find_elements(By.CSS_SELECTOR, 'em')
print(elements)
for element in elements:
logger.info(f"实际结果为{element.text},预期结果为{search_content}")
index_num = str(elements.index(element))
self.driver.save_screenshot("search_content"+index_num+".jpg")
def test_page_source(self):
# 保存页面源码
search_content = "selenium"
self.driver.get("https://www.sogou.com/")
self.driver.find_element(By.ID, "query").send_keys(search_content)
logger.debug(self.driver.page_source)
with open("../log/log1.html", "x", encoding="u8") as file:
file.write(self.driver.page_source)

浏览器复用

步骤

1、获取浏览器的路径
image

2、配置环境变量到path
image

3、关闭所有chrome浏览器并关闭进程
cmd运行chrome --remote-debugging-port=9222
4、使用浏览器复用操作

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
# 定义配置的实例对象
option = Options()
# 修改实例属性为debug模式启动的ip+端口
option.debugger_address = "localhost:9222"
# 实例化driver的时候,添加option配置
driver = webdriver.Chrome(options=option)
driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx")

Cookie复用

import json
import time
import yaml
from selenium import webdriver
class TestChromeCookie:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
self.driver.implicitly_wait(3)
def test_get_cookie(self):
# 获取cookie并把内容写入到文件中
self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx")
time.sleep(20)
cookie = self.driver.get_cookies()
with open("../cookie/cookie.yaml", "w") as filter:
yaml.dump(cookie, filter)
print(cookie)
def test_add_cookie(self):
# 使用cookie进行登录
# cookies = self.test_get_cookie()
self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx")
cookies = yaml.safe_load(open("../cookie/cookie.yaml"))
for cookie in cookies:
self.driver.add_cookie(cookie)
self.driver.get("https://work.weixin.qq.com/wework_admin/loginpage_wx")
time.sleep(5)

异常截图并导入到报告中

import time
import allure
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
class TestBaidu:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
def test_baidu(self):
self.driver.get("https://www.baidu.com")
try:
self.driver.find_element(By.ID, "su")
except Exception:
print("出现异常啦")
timestamp = int(time.time())
# 截图
image_path = f"../images/image_{timestamp}.png"
page_source_path = f"../page_source/page_source_{timestamp}.html"
self.driver.save_screenshot(image_path)
# 记录page_source
with open(page_source_path, mode="w", encoding='u8') as f:
f.write(self.driver.page_source)
allure.attach.file(image_path, name="picture", attachment_type=allure.attachment_type.PNG)
allure.attach.file(page_source_path, name="page_source", attachment_type=allure.attachment_type.HTML)
# 将异常抛出
raise Exception

通过命令行进行运行生成allure需要加载的内容
pytest python文件路径 --alluredir=./reports
然后通过allure命令进行allure测试报告进行读取
allure serve ./reports

代码优化

import time
import allure
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from util.decorators_util import ui_exception_record
"""
把装饰器的架子搭好
把相关的逻辑嵌套进来
问题1:
需要通过driver实例截图/打印page_source,装饰器需要先去获取driver对象
解决方案:
1、通过setup_class进行driver对象的声明
2、在使用driver之前声明driver
问题2:
隐藏的Bug:一旦被装饰方法有返回值,会丢失返回值
解决方法:
当被装饰方法被执行的时候,添加return
"""
class TestBaidu:
def setup_class(self):
self.driver = webdriver.Chrome()
self.driver.maximize_window()
def tear_down(self):
self.driver.quit()
@ui_exception_record
def find(self):
return self.driver.find_element(By.ID, "su1")
# 使用装饰器进行代码优化
def test_baidu(self):
self.driver.get("https://www.baidu.com")
self.find().click()

装饰器工具封装

# 通过装饰器进行优化代码
import allure
def ui_exception_record(func):
def inner(*args, **kwargs):
# 获取被装饰方法的self也就是实例方法
# 通过self就可以拿到声明的实例变量driver
# 前提条件:
# 1、被装饰的方法是一个实例方法
# 2、实例需要有实例变量self.driver
try:
# 当被装饰方法、函数发生异常就捕获并做数据记录
return func(*args, **kwargs)
except Exception:
driver = args[0].driver
print("出现异常啦")
timestamp = int(time.time())
# 截图
image_path = f"../images/image_{timestamp}.png"
page_source_path = f"../page_source/page_source_{timestamp}.html"
driver.save_screenshot(image_path)
# 记录page_source
with open(page_source_path, mode="w", encoding='u8') as f:
f.write(driver.path_source)
allure.attach.file(image_path, name="picture", attachment_type=allure.attachment_type.PNG)
allure.attach.file(page_source_path, name="page_source", attachment_type=allure.attachment_type.TEXT)
# # 将异常抛出
raise Exception
return inner

page object设计模式

POM建模原则

字段意义

不要暴露页面内部的元素给外部
不需要建模UI内的所有元素

方法意义

用公共方法代表UI所提供的功能
方法应该返回其他的PageObject或者返回用于断言的数据
同样的行为不同的结果可以建模为不同的方法
不要在方法内加断言

把元素信息和操作细节封装到PageObject类中
根据业务逻辑,在测试用例中链式调用

Django

创建项目方式

访问进入到想要放置项目的地址
终端运行命令
django-admin startproject 项目名

快速上手

确保App已注册 setting.py
在setting.py文件中注册App

from django.apps import AppConfig
class App01Config(AppConfig):
default_auto_field = 'django.db.models.BigAutoField'
name = 'DjangoTryProject'
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'DjangoProject.apps'
]
# 新版本Django不用写方法名 直接写应用名就能够注册

编写url和视图函数对应关系 ursl.py
如果访问 域名/index/,将会找到view中的index方法并执行index方法

from DjangoTryProject import view
urlpatterns = [
# path('admin/', admin.site.urls),
path('index/', view.index),
]

image

编写视图函数

from django.http import HttpResponse
def index(request):
return HttpResponse("欢迎使用Django")

启动Django项目
命令行方式

python manager.py runserver

pycharm直接运行

跟前端文件联动

创建一个templates文件夹,里面放需要使用的前端html文件

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试Django</title>
</head>
<body>
<h1>用户列表</h1>
</body>
</html>
from django.http import HttpResponse
from django.shortcuts import render
def index(request):
return HttpResponse("欢迎使用Django")
def user_list(request):
return render(request, "user_list.html")

静态文件

放到static文件夹并用文件夹区分好
image.png

静态文件引入

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试Django</title>
</head>
<body>
<h1>用户列表</h1>
</body>
<script src="{% static 'js/jquery.js' %}"></script>
</html>

模版语法

通过在html文件中填写占位符,然后由数据对这些占位符进行替换和处理

def tpl(request):
name = "tpl测试"
roles = ["admin","user","CES"]
user_info = {"name":"郭嘉","salary":2000,"role":"CTO"}
data_list = [
{"name": "曹操", "salary": 2000, "role": "CTO"},
{"name": "郭嘉", "salary": 2000, "role": "CTO"},
{"name": "张飞", "salary": 2000, "role": "CTO"}
]
return render(request, "tpl.html", {"n1":name,"n2":roles,"n3":user_info,"n4":data_list})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>tpl</title>
</head>
<body>
<h1>模版语法的学习</h1>
<div>{{ n1 }}</div>
<div>
{% for item in n2 %}
<span>{{ item }}</span>
{% endfor %}
</div>
<hr>
<ul>
{% for item in n3.values %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<hr>
{{ n4 }}
{{ n4.0.name }}
{{ n4.0.salary }}
{{ n4.0.role }}
<hr>
{% for foo in n4 %}
<div>{{ foo.name }}</div>
<div>{{ foo.salary }}</div>
<div>{{ foo.role }}</div>
{% endfor %}
<hr>
{% if n1 == "tpl测试" %}
<div>tpl测试</div>
{% else %}
<div>tpl测试失败</div>
{% endif %}
</body>
</html>

模版语法实战

def news(request):
import requests
result = requests.get(
url="https://i.news.qq.com/gw/event/pc_hot_ranking_list?ids_hash=&offset=0&page_size=50&appver=15.5_qqnews_7.1.60&rank_id=hot"
)
data_list = result.json()["idlist"][0]["newslist"]
return render(request, "news.html", {"result": data_list})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>腾讯新闻</title>
</head>
<body>
<ul>
{% for foo in result %}
<li>{{ foo.id }}</li>
<li>{{ foo.articletype }}</li>
<li>{{ foo.picShowType }}</li>
<li>{{ foo.title }}</li>
{% endfor %}
</ul>
{{ result }}
</body>
</html>

用户访问逻辑

用户访问地址,会到urls.py匹配到对应的方法,然后到view.py中找到这个方法,再又这个方法的模版页面替换里面的数据,然后再渲染给用户
image.png

获取url的传参

  • request.GET方法能够获取param
  • request.POST方法能够获取到POST请求的请求体
  • request.method方法能够获取请求方式

return的内容

  • redirect重定向
  • render方法页面模版
  • HttpResponse响应

提交表单

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login/" method="post" >
{% csrf_token %}
<input type="text" name="user" placeholder="用户名">
<input type="password" name="password" placeholder="密码">
<input type="submit" value="提交">{{ error_message }}
</form>
</body>
</html>

表单提交的时候,需要在form中补充{% csrf_token %}才不会报错
{{ error_message }}如果需要出现报错信息,就可以在方法中补充传值

def login(request):
if request.method == "GET":
return render(request, "login.html")
user = request.POST.get("user")
password = request.POST.get("password")
if user == "root" and password == "1234":
print(request.POST)
return render(request, "login.html", {"error_message":"登录成功"})
else:
return render(request, "login.html", {"error_message":"用户名或密码错误"})

数据库操作

Django开发操作数据库更简单,内部提供了ORM框架

安装第三方模块mysqlclient
pip install mysqlclient
ORM作用
  • 不用亲自写SQL语句
  • 创建修改删除数据库中的表(无法创建database)
  • 操作表中的数据
Django连接数据库
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",#使用的引擎包
"NAME": "",#数据库database名称
"USER": "",#数据库账号
"PASSWORD": "",#数据库密码
"HOST": "",#本地ip
"PORT": "",#端口号
}
}
创建表
from django.db import models
"""
自动运行以下代码
create table DjangoProject_userinfo(
id bigint primary key autoincrement,
name varchar(32),
password varchar(64),
age int
)
"""
class User_info(models.Model):
name = models.CharField(max_length=32)
age = models.IntegerField()
password = models.CharField(max_length=64)
text = models.CharField(max_length=16)
textname = models.CharField(max_length=16,default=2)
# 如果希望字段可以为空,可以传参null=True,blank=True
#如果要在已有的表里面新增字段,需要添加默认值,或者新增字段的时候赋予默认值
#如果需要删除表, 直接删除class就可以
class department(models.Model):
name = models.CharField(max_length=16)
class role(models.Model):
name = models.CharField(max_length=16)

cmd运行(大前提:App必须已经注册)

python.exe .\manage.py makemigrations APP名称
python.exe .\manage.py migrate
# 如果出现了报错django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.5.27).
# 可以访问到C:\Users\方振钦\AppData\Local\Programs\Python\Python39\Lib\site-packages\django\db\backends\base下的bash.py文件中
# 找到self.check_database_version_supported()并注释掉
新建数据
department.object.create(name="销售部")
# 运行python manage.py migrate,会在mysql中生成数据
# 不能用python manage.py makemigrations来运行,会生成两份数据
def orm(request):
if request.method == 'GET':
return render(request, "orm.html")
username = request.POST.get("name")
age = request.POST.get("age")
password = request.POST.get("password")
text = request.POST.get("text")
#插入数据
User_info.objects.create(name= username, age = age, password =password, text = text)
#删除id=1的数据
User_info.objects.filter(id="1").delete()
#删除表中全部的数据
User_info.objects.all().delete()
#获取数据
userObject = User_info.objects
user_list = User_info.objects.all()
for user in user_list:
print(user.name, user.password, user.age, user.text)
# print(user_list)
userObject.filter(id=1).update(password = 123123)
first = userObject.filter(id=1).first()
print(first.name, first.age, first.text, first.password)
return HttpResponse("上传成功")
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>orm</title>
</head>
<body>
<form action="/orm/" method="post">
{% csrf_token %}
<input type="text" placeholder="name" name="name">
<input type="text" placeholder="age" name="age">
<input type="password" placeholder="password" name="password">
<input type="text" placeholder="text" name="text">
<input type="submit" value="提交">
</form>
</body>
</html>
posted @   倒影先生  阅读(11)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示