Python 框架学习 Django篇 (六) ORM关联

像是上一章我们很少会通过页面点击去添加和绑定关系表,更多的时候都是通过django的语法实现,接下来我们做一个案例 django rom是怎么操作外键关系的

创建mode模型表

Django_demo/mgr/models.py

# 国家表
class Country(models.Model):name = models.CharField(max_length=100)# 学生表, country 字段是国家表的外键,形成一对多的关系
class Student(models.Model):name    = models.CharField(max_length=100)grade   = models.PositiveSmallIntegerField()country = models.ForeignKey(Country,on_delete=models.PROTECT)
python manage.py makemigrations 
python manage.py migrate

添加测试数据

python manage.py shell
#注意应用名称
from paas.models import *
c1 = Country.objects.create(name='中国')
c2 = Country.objects.create(name='美国')
c3 = Country.objects.create(name='法国')
Student.objects.create(name='白月', grade=1, country=c1)
Student.objects.create(name='黑羽', grade=2, country=c1)
Student.objects.create(name='大罗', grade=1, country=c1)
Student.objects.create(name='真佛', grade=2, country=c1)
Student.objects.create(name='Mike', grade=1, country=c2)
Student.objects.create(name='Gus',  grade=1, country=c2)
Student.objects.create(name='White', grade=2, country=c2)
Student.objects.create(name='Napolen', grade=2, country=c3)

一、外键表使用

1、字段访问

#获取student表中 name='白月' 的数据
s1 = Student.objects.get(name='白月')#将拿到的数据通过外键直接获取到对应外键表的name字段数据并输出 
s1.country.name 

案例

>>> s1 = Student.objects.get(name='白月') 
>>> s1.country.name 
'中国' 

2、单个字段过滤

如果我们想要查询学生表中所有关于1年纪的学生,对应表字段是grade 年纪

Student.objects.filter(grade=1).values()

返回

<QuerySet [{'id': 1, 'name': '白月', 'grade': 1, 'country_id': 1}, {'id': 3, 'name': '大罗', 'grade': 1, 'country_id': 1}, {'id': 5, 'name': 'Mike', 'grade': 1, 'country_id': 2}, {
'id': 6, 'name': 'Gus', 'grade': 1, 'country_id': 2}]>

3、多字段过滤

如果我要同时实现多个条件呢,比如同时满足一年级, 并且国籍是中国的学生

我们不能直接添加多个选项  Student.objects.filter(grade=1,country='中国')

因为,Student表中 country 并不是国家名称字符串字段,而是一个外键字段,对应 Country 表中 id 字段,或许我们可以和上一张用sql语句一样,先查id,然后在查其他信息

cn = Country.objects.get(name='中国')
Student.objects.filter(grade=1,country_id=cn.id).values()#或者cn = Country.objects.get(name='中国')
Student.objects.filter(grade=1,country=cn).values()

 返回

>>> cn = Country.objects.get(name='中国') 
>>> Student.objects.filter(grade=1,country_id=cn.id).values() 
<QuerySet [{'id': 1, 'name': '白月', 'grade': 1, 'country_id': 1}, {'id': 3, 'name': '大罗', 'grade': 1, 'country_id': 1}]> >>> cn = Country.objects.get(name='中国') 
>>> Student.objects.filter(grade=1,country=cn).values() 
<QuerySet [{'id': 1, 'name': '白月', 'grade': 1, 'country_id': 1}, {'id': 3, 'name': '大罗', 'grade': 1, 'country_id': 1}]> 

4、多字段过滤优化

但是上面的方法其实相对来说过于繁琐,并且需要查询两次,性能不高,

Django ORM 中,对外键关联,有更方便的语法,使用外键+ 双下划线 + 字段名称

Student.objects.filter(grade=1,country__name='中国').values()

 返回

<QuerySet [{'id': 1, 'name': '白月', 'grade': 1, 'country_id': 1}, {'id': 3, 'name': '大罗', 'grade': 1, 'country_id': 1}]> 

5、过滤优化--指定显示字段

如果返回结果只需要 学生姓名 和 国家名两个字段,可以这样指定values内容

Student.objects.filter(grade=1,country__name='中国').values('name','country__name')

 返回

<QuerySet [{'name': '白月', 'country__name': '中国'}, {'name': '大罗', 'country__name': '中国'}]>

6、字段显示重命名

有个问题,我们返回数据的字段是country__name 这样的,双下划线很奇怪,有时候前后端定义好了接口格式,必须让用countryname的话就需要去做字段的重命名

from django.db.models import F# annotate 可以将表字段进行别名处理
Student.objects.annotate(countryname=F('country__name'),studentname=F('name'))\.filter(grade=1,countryname='中国').values('studentname','countryname')

7、反向访问

 Django ORM中,关联表正向关系是通过表外键字段(或者多对多)表示

而反向访问,则是通过将model模板名称转换成小写表示的,比如说你已经获取到了某个国家信息,需要通过国家信息反向查看属于这个国家的学生数据

 案例

#声明获取国家表中name字段为中国的数据
cn = Country.objects.get(name='中国')#先将要查看的表改为全小写,并且声明_set来获取所有的反向外键关联对象
cn.student_set.all()

返回

>>> cn = Country.objects.get(name='中国') 
>>> cn.student_set.all() 
<QuerySet [<Student: Student object (1)>, <Student: Student object (2)>, <Student: Student object (3)>, <Student: Student object (4)>]> 
>>>  

小知识

Django还给出了一个方法,是在定义Model的时候,外键字段使用 related_name 参数

#国家表
class Country(models.Model):name = models.CharField(max_length=100)# country 字段是国家表的外键,形成一对多的关系
class Student(models.Model):name    = models.CharField(max_length=100)grade   = models.PositiveSmallIntegerField()country = models.ForeignKey(Country,on_delete = models.PROTECT,# 指定反向访问的名字related_name='students')
python manage.py makemigrations 
python manage.py migrate

查询

cn = Country.objects.get(name='中国')
students = cn.students.all()#拿到的值循环存储并且输出
student_names = [student.name for student in students]print(student_names)

返回

>>> print(student_names)
['白月', '黑羽', '大罗', '真佛'] 

8、反向过滤

如果我们想要获取所有一年纪学生的国家名称呢,同样可以依靠复合查询实现

# 先获取所有的一年级学生id列表
country_ids = Student.objects.filter(grade=1).values_list('country', flat=True)# 再通过id列表使用  id__in  过滤
Country.objects.filter(id__in=country_ids).values()

存在的问题就是重复请求,造成性能下降 ,用Django ORM 的方法

Country.objects.filter(students__grade=1).values()

 返回

>>> Country.objects.filter(students__grade=1).values() 
<QuerySet [{'id': 7, 'name': '中国'}, {'id': 7, 'name': '中国'}, {'id': 8, 'name': '美国'}, {'id': 8, 'name': '美国'}]> 

发现存在重复的数据,我们使用 .distinct() 去重

>>> Country.objects.filter(students__grade=1).values().distinct() 
<QuerySet [{'id': 7, 'name': '中国'}, {'id': 8, 'name': '美国'}]> 

 注意

我们前面在定义学生表时, 使用了related_name = "students" 去指定了反向关联students

所以这里通过国家表查询学生表数据的时候使用的字段名称是students__grade 的反向关联名称

如果定义时,没有指定related_name, 则应该使用 表名转化为小写 ,就是这样

Country.objects.filter(student__grade=1).values()

二、实现项目代码

我们在 mgr 目录下面新建 order.py 处理 客户端发过来的 列出订单、添加订单 的请求

1、添加增删改查主体程序

vi Django_demo/mgr/order.py

from django.http import JsonResponse
from django.db.models import F
from django.db import IntegrityError, transaction# 导入 Order 对象定义
from  paas.models import  Order,OrderMedicineimport jsondef dispatcherorder(request):# 根据session判断用户是否是登录的管理员用户if 'usertype' not in request.session:return JsonResponse({'ret': 302,'msg': '未登录','redirect': '/mgr/sign.html'},status=302)if request.session['usertype'] != 'mgr':return JsonResponse({'ret': 302,'msg': '用户非mgr类型','redirect': '/mgr/sign.html'},status=302)# 将请求参数统一放入request 的 params 属性中,方便后续处理# GET请求 参数 在 request 对象的 GET属性中if request.method == 'GET':request.params = request.GET# POST/PUT/DELETE 请求 参数 从 request 对象的 body 属性中获取elif request.method in ['POST','PUT','DELETE']:# 根据接口,POST/PUT/DELETE 请求的消息体都是 json格式request.params = json.loads(request.body)# 根据不同的action分派给不同的函数进行处理action = request.params['action']if action == 'list_order':return listorder(request)elif action == 'add_order':return addorder(request)# 订单 暂 不支持修改 和删除else:return JsonResponse({'ret': 1, 'msg': '不支持该类型http请求'})

2、添加路由

vi  Django_demo/mgr/urls.py


urlpatterns = [...path('orders', dispatcherorder), # 加上这行...
]

3、定义添加订单函数

接下来,我们添加函数 addorder,来处理添加订单请求,首先我们要了解的是

每次添加一个订单,都需要在2张表(Order 和 OrderMedicine )中添加记录 订单表和中间表

我们给两张表添加记录,就会往数据库写两次,如果中有一次写入失败了,就会形成脏数据

而对应解决这个问题的办法,就是利用数据库"事务"的机制

什么是事务

    把一批数据库操作放在 事务 中, 该事务中的任何一次数据库操作 失败了, 数据库系统就会让 整个事务就会发生回滚,撤销前面的操作, 数据库回滚到这事务操作之前的状态

在django中使用事务机制

直接通过关键字with transaction.atomic()  即可实现数据库批量操作

 Django_demo/mgr/order.py

def addorder(request):info  = request.params['data']# 从请求消息中 获取要添加订单的信息# 并且插入到数据库中#设置事务with transaction.atomic():new_order = Order.objects.create(name=info['name'] ,customer_id=info['customerid'])batch = [OrderMedicine(order_id=new_order.id,medicine_id=mid,amount=1)for mid in info['medicineids']]#  在多对多关系表中 添加了 多条关联记录OrderMedicine.objects.bulk_create(batch)return JsonResponse({'ret': 0,'id':new_order.id})

只要是在 with transaction.atomic() 下面 缩进部分的代码,对数据库相关的操作都视为在同一个事务中,如果其中有任何一步数据操作失败了, 前面的操作都会回滚,这样就解决了多次写入失败导致的脏数据问题

代码说明

batch = [OrderMedicine(order_id=new_order.id,medicine_id=mid,amount=1)for mid in info['medicineids']]#  在多对多关系表中 添加了 多条关联记录OrderMedicine.objects.bulk_create(batch)

正常来说,OrderMedicine 对应的是订单和药品的多对对记录关系表,要在多对多表中加上关联记录,就是添加一条记录,直接写入即可,如下

OrderMedicine.objects.create(order_id=new_order.id,medicine_id=mid,amount=1)

但你实际上去买药的时候,很少会单独买一样,多少要带点其他的 ,但是我们如果直接用循环把去写入上面的语句,循环几次插入几次,那么多次写入也会影响性能,我们可以使用django中的bulk_create 把多条数据的插入,放在一个SQL语句中完成

batch = [OrderMedicine(order_id=new_order.id,medicine_id=mid,amount=1)  for mid in info['medicineids']]#  在多对多关系表中 添加了 多条关联记录
OrderMedicine.objects.bulk_create(batch)

三、ORM 外键关联

接下来我们编写listorder 函数用来处理 列出订单请求,请求格式如下

[{id: 1, name: "华山医院订单001", create_date: "2018-12-26T14:10:15.419Z",customer_name: "华山医院",medicines_name: "青霉素"},{id: 2, name: "华山医院订单002", create_date: "2018-12-27T14:10:37.208Z",customer_name: "华山医院",medicines_name: "青霉素 | 红霉素 "}
] 

 1、基于接口案例返回值

 其中 ‘id’,’name’,‘create_date’ 这些字段的内容获取很简单,order表中就有这些字段

def listorder(request):# 返回一个 QuerySet 对象 ,包含所有的表记录qs = Order.objects.values('id','name','create_date')return JsonResponse({'ret': 0, 'retlist': newlist})

 但是customer_name 客户名称 medicines_name 药品名称是在订单表里面没有的,我们需要通过类似前面的方法从订单表的外键customer 获取到客户表的name字段,方法就是模型名称小写 + 双下划线 + 字段名称

def listorder(request):qs = Order.objects\.values('id','name','create_date',# 两个下划线,表示取customer外键关联的表中的name字段的值'customer__name')# 将 QuerySet 对象 转化为 list 类型retlist = list(qs)return JsonResponse({'ret': 0, 'retlist': retlist})

同样的道理 , 订单对应 的药品 名字段,是多对多关联, 也同样可以用 两个下划线 获取 关联字段的值

 Django_demo/mgr/order.py 

def listorder(request):qs = Order.objects\.values('id','name','create_date','customer__name',# 两个下划线,表示取medicines 关联的表中的name字段的值# 如果有多个,就会产生多条记录'medicines__name')# 将 QuerySet 对象 转化为 list 类型retlist = list(qs)return JsonResponse({'ret': 0, 'retlist': retlist})

2、重命名返回字段

 这个是能返回数据了,但存在的问题是双下划线和接口要求的单下划线不同,需要通过annotate做一下重命名

from django.db.models import Fdef listorder(request):# 返回一个 QuerySet 对象 ,包含所有的表记录qs = Order.objects\.annotate(customer_name=F('customer__name'),medicines_name=F('medicines__name'))\.values('id','name','create_date','customer_name','medicines_name')# 将 QuerySet 对象 转化为 list 类型retlist = list(qs)return JsonResponse({'ret': 0, 'retlist': retlist})

3、去除订单内多个不同药品

如果一个订单里面有多个药品,就会产生多条记录, 这不是我们要的。

根据接口,一个订单里面的多个药品, 用 竖线 隔开

def listorder(request):# 返回一个 QuerySet 对象 ,包含所有的表记录qs = Order.objects\.annotate(customer_name=F('customer__name'),medicines_name=F('medicines__name'))\.values('id','name','create_date','customer_name','medicines_name')# 将 QuerySet 对象 转化为 list 类型retlist = list(qs)# 可能有 ID相同,药品不同的订单记录, 需要合并newlist = []id2order = {}for one in retlist:orderid = one['id']if orderid not in id2order:newlist.append(one)id2order[orderid] = oneelse:id2order[orderid]['medicines_name'] += ' | ' + one['medicines_name']return JsonResponse({'ret': 0, 'retlist': newlist})

4、测试--获取订单信息

import  requests,pprint#添加认证
payload = {'username': 'root','password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')# 构建添加 客户信息的 消息体,是json格式
payload = {"action":"list_order",
}
url='http://127.0.0.1:8000/api/mgr/orders/'if set_cookie:# 将Set-Cookie字段的值添加到请求头中headers = {'Cookie': set_cookie}# 发送请求给web服务response = requests.post(url,json=payload,headers=headers)pprint.pprint(response.json())

返回

{'ret': 0,'retlist': [{'create_date': '2023-10-25T03:08:00Z','customer_name': 'zhangsan','id': 5,'medicines_name': 'gmkl','name': 'test'}]}

5、测试--添加订单信息

import  requests,pprint#添加认证
payload = {'username': 'root','password': '12345678'
}
#发送登录请求
response = requests.post('http://127.0.0.1:8000/api/mgr/signin',data=payload)
#拿到请求中的认证信息进行访问
set_cookie = response.headers.get('Set-Cookie')# 构建添加 客户信息的 消息体,是json格式
payload = {"action":"add_order",             #模式改为添加"data": {"name": "天山订单",                 #订单名称自定义"customerid": 1,              #客户表中的id值"medicineids": ["6"]          #这个是药品表中的id值}
}
url='http://127.0.0.1:8000/api/mgr/orders/'if set_cookie:# 将Set-Cookie字段的值添加到请求头中headers = {'Cookie': set_cookie}# 发送请求给web服务response = requests.post(url,json=payload,headers=headers)pprint.pprint(response.json())

四、特殊字段参数使用

1、唯一性约束处理

我在实际使用的是时候为数据的一致性,我给好几个字段,都添加了唯一性约束

ip_address = modes.CharField(max_length=200,unique=True)

但是在写入的时候如果某个字段发现因为已经有相同数据程序就会崩掉,我们要就不能直接使用create去添加数据,而是改用get_or_create

 案例

#处理数据逻辑
obj, created = clusterINFO.objects.get_or_create(唯一性字段=传入的值比如ip, 唯一性字段2=传入的值2, #表内其他非一致性字段defaults={'other_field': other_value}
)

上面这个方法当发现已经有字段时,则会给created变量返回一个值为false,如果发现可以正常写入就会返回一个true

2、传入值处理

一开始总是陷入一个误区,想着表内要啥数据就从客户端传啥数据

payload = {"action":"list_order","data": {key: valuekey: value}
}

 比方说,我要添加集群中的node数据,肯定要确保有这个集群名称吧,还要确定下集群的园区是什么,这些都不是node表里面有的,但也要跟随传输过去处理

#拿到请求后先去集群表里面去查环境和集群名对应的字段数据
cn = 集群表.objects.get(环境=  ,集群名=)#到到的cn如果没有报错就是存放着对应环境集群那一行的数据
cn.id  就能拿到id值了,剩下的就是写入#给node表插入数据
obj, created = clusterINFO.objects.get_or_create(...defaults={'node表关联的外键字段_id': cn.id  #给node表外键提供主键表的id值#这块外键的字段名要加_id表示外键表名}
)

3、前端代码访问api数据

把这个文件扔到templates模板目录下面,定义个路由从页面显示出来,在页面打开的时候自动去获取订单表信息循环打印出来

<html>
<head><title>Your Page Title</title>
</head>
<body>
<h1>Your Page Content</h1><div id="list-container"></div><!-- 将 JavaScript 代码放在 <script> 标签中 -->
<script>// 定义请求参数const params = {action: 'list_order'};fetch('/api/mgr/orders/',{method: 'POST',headers: {'Content-Type': 'application/json'},body: JSON.stringify(params)})//获取请求的结果数据json.then(response => response.json()).then(data => {// 打印返回的 JSON 数据console.log(data);// 解析JSON数据并提取retlist的值const retlistValues = data.retlist; // retlist的值是一个包含多个JSON对象的数组console.log(retlistValues)//获取页面div,一会把自定义的div加进去const existingDiv = document.getElementById("list-container")// 遍历retlist的值,并将字段显示在页面上retlistValues.forEach(obj => {// 在页面上创建新的元素来显示字段和值const div = document.createElement('div');for (let key in obj) {const span = document.createElement('span');span.innerText = `${key}: ${obj[key]}`;div.appendChild(span);}existingDiv.appendChild(div)});})</script>
</body>
</html>

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

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

相关文章

MAC下安装Python

MAC基本信息&#xff1a; 执行命令&#xff1a; brew install cmake protobuf rust python3.10 git wget 遇到以下问题&#xff1a; > Downloading https://mirrors.aliyun.com/homebrew/homebrew-bottles/rust-1.59.0 Already downloaded: /Users/xxxx/Library/Caches/Ho…

BaiChuan-QWen

QWen Tokenizer 选择byte pair encoding (BPE)作为分词方法vacabulary在中文上做了增强&#xff0c;验证增加vocabulary的规模不会为下游任务带来负面影响 Model Positional embedding&#xff1a;选择RoPE&#xff0c;反向更新时选择FP32的精度而不是FP16或BP16&#xff0c…

Golang 自定义函数库(个人笔记)

1.用字符串连接切片元素&#xff08;类似php implode&#xff09; package mainimport ("fmt""strconv""strings" )func main() {data : []int{104, 101, 108, 108, 111}fmt.Println(IntSliceToString(data, ",")) }func IntSliceToS…

在pycharm中,远程操作服务器上的jupyter notebook

一、使用场景 现在我们有两台电脑&#xff0c;一台是拥有高算力的服务器&#xff0c;另一台是普通的轻薄笔记本电脑。如何在服务器上运行jupyter notebook&#xff0c;同时映射到笔记本电脑上的pycharm客户端中进行操作呢&#xff1f; 二、软件 pycharm专业版&#xff0c;jupy…

Spark新特性与核心概念

一、Sparkshuffle &#xff08;1&#xff09;Map和Reduce 在shuffle过程中&#xff0c;提供数据的称之为Map端&#xff08;Shuffle Write&#xff09;&#xff0c;接受数据的称之为Redeuce端&#xff08;Shuffle Read&#xff09;&#xff0c;在Spark的两个阶段中&#xff0c;总…

【斗罗二】王东升级三环,戴华斌挑衅,雨浩单手接鼎订下赌约

【侵权联系删除】【文/郑尔巴金】 深度爆料&#xff0c;《绝世唐门》第20集&#xff0c;一场瞩目的战斗即将爆发。王冬&#xff0c;这位一年级的强攻系班长&#xff0c;将与戴华斌进行一场激烈的较量。王冬拥有三大武魂&#xff0c;其中最为人们所熟知的是那光明女神蝶&#x…

liunx Centos-7.5上 rabbitmq安装

在安装rabbitmq中需要注意&#xff1a; 1、rabbitmq依赖于erlang&#xff0c;需要先安装erlang 2、erlang和rabbitmq版本有对应关系 可参考网页&#xff1a;https://www.rabbitmq.com/which-erlang.html 第一步&#xff0c;安装编译工具及库文件,如果服务器上已经有了&…

网络协议--TCP:传输控制协议

17.1 引言 本章将介绍TCP为应用层提供的服务&#xff0c;以及TCP首部中的各个字段。随后的几章我们在了解TCP的工作过程中将对这些字段作详细介绍。 对TCP的介绍将由本章开始&#xff0c;并一直包括随后的7章。第18章描述如何建立和终止一个TCP连接&#xff0c;第19和第20章将…

java项目之时间管理系统(ssm框架)

项目简介 时间管理系统实现了以下功能&#xff1a; 管理员&#xff1a;个人中心、用户管理、分类列表管理、在线学习管理、励志视频管理、活动项目管理、活动报名管理、目标制定管理、论坛管理、系统管理。用户&#xff1a;注册、个人中心、活动报名管理、目标制定管理、我的…

【OpenCV实现平滑图像金字塔,轮廓:入门】

文章目录 概要图像金字塔轮廓&#xff1a;入门 概要 文章内容的概要&#xff1a; 平滑图像金字塔&#xff1a; 图像金字塔是什么&#xff1f; 图像金字塔是指将原始图像按照不同的分辨率进行多次缩小&#xff08;下采样&#xff09;得到的一系列图像。这种处理方式常用于图像…

【git】git使用教程

1、版本管理工具 如果有一个软件能记录我们对文档的所有修改&#xff0c;所有版本&#xff0c;这类软件我们一般叫做版本控制工具。 特性“ 能够记录历史版本&#xff0c;回退历史版本团队开发&#xff0c;方便代码合并 2、版本管理工具介绍 svn、git svn是集中式版本控制…

Redis快速上手篇(六)主从复制

主从复制 主机数据更新后根据配置和策略&#xff0c; 自动同步到备机的master/slaver机制&#xff0c;Master以写为主&#xff0c;Slave以读为主 读写分离&#xff0c;性能扩展&#xff08;主 写 从 读&#xff09; 容灾快速恢复 主从复制的作用 1、数据冗余&#xff1a;主从复…

Go 的连接池、重试和超时

这是一个来自 API 的间歇性 500 个内部服务器错误的故事&#xff0c;这些错误最终是由 Go 包中的硬编码常量引起的database/sql。我将主要为您省去冗长的故事&#xff0c;并直接讨论问题以及我们发现的原因。我们注意到来自特定 API 端点的 500 错误数量有所增加&#xff0c;并…

大模型在百度智能问答、搜索中的应用

本文主要介绍了智能问答技术在百度搜索中的应用。包括机器问答的发展历程、生成式问答、百度搜索智能问答应用。欢迎大家加入百度搜索团队&#xff0c;共同探索智能问答技术的发展方向&#xff0c;文末有简历投递方式。 01 什么是机器问答 机器问答&#xff0c;就是让计算机…

H5游戏源码分享-考眼力游戏猜猜金币在哪

H5游戏源码分享-考眼力游戏猜猜金币在哪 <!DOCTYPE html> <html> <head><meta http-equiv"Content-Type" content"text/html; charsetUTF-8"><meta charset"UTF-8"><meta name"apple-mobile-web-app-capa…

docker 部署tig监控服务

前言 tig对应的服务是influxdb grafana telegraf 此架构比传统的promethus架构更为简洁&#xff0c;虽然influxdb开源方案没有集群部署&#xff0c;但是对于中小型服务监控需求该方案简单高效 本文以docker-compose来演示这套监控体系的快速搭建和效果。 部署 docker-compos…

Wpf 使用 Prism 实战开发Day02

一.设计首页导航条 导航条的样式&#xff0c;主要是从Material DesignThemes UI 拷贝过来修改的,项目用了这个UI组件库&#xff0c;就看自己需要什么&#xff0c;就去拷过来使用&#xff0c;界面布局或其他组件使用&#xff0c;不做介绍。 直接下载源码&#xff0c;编译运行就可…

STM32F10xx 存储器和总线架构

一、系统架构 在小容量、中容量和大容量产品 中&#xff0c;主系统由以下部分构成&#xff1a; 四个驱动单元 &#xff1a; Cotex-M3内核、DCode总线&#xff08;D-bus&#xff09;和系统总线&#xff08;S-bus&#xff09; 通用DMA1和通用DMA2 四个被动单元 内部SRAM 内部…

独创改进 | RT-DETR 引入 Asymptotic Hybrid Encoder | 渐进混合特征解码结构

本专栏内容均为博主独家全网首发,未经授权,任何形式的复制、转载、洗稿或传播行为均属违法侵权行为,一经发现将采取法律手段维护合法权益。我们对所有未经授权传播行为保留追究责任的权利。请尊重原创,支持创作者的努力,共同维护网络知识产权。 文章目录 网络结构实验结果…

asp.net老年大学教务管理信息系统VS开发sqlserver数据库web结构c#编程

一、源码特点 asp.net 老年大学教务管理信息系统是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使 用c#语言开发 asp.net老年大学教务管理…