一、数据表关联

1、一对多

  vi Django_demo/paas/models.py

class Customer(models.Model):
    # 客户名称
    name = models.CharField(max_length=200)

    # 联系电话
    phonenumber = models.CharField(max_length=200)

    # 地址
    address = models.CharField(max_length=200)

  vi Django_demo/paas/models.py

class Medicine(models.Model):
    # 药品名
    name = models.CharField(max_length=200)
    # 药品编号
    sn = models.CharField(max_length=200)
    # 描述
    desc = models.CharField(max_length=200)

 Python 框架学习 Django篇 (六) 数据表关联、ORM关联-LMLPHP

#导入数据库
python manage.py makemigrations
python manage.py migrate 

#查看
desc paas_customer;

Python 框架学习 Django篇 (六) 数据表关联、ORM关联-LMLPHP

 vi Django_demo/paas/models.py

import datetime
class Order(models.Model):
    # 订单名
    name = models.CharField(max_length=200,null=True,blank=True)

    # 创建日期
    create_date = models.DateTimeField(default=datetime.datetime.now)

    # 客户
    customer = models.ForeignKey(Customer,on_delete=models.PROTECT)

注意

python manage.py makemigrations
python manage.py migrate 

#查看
desc paas_info;

返回

mysql> desc paas_order;
+-------------+--------------+------+-----+---------+----------------+
| Field       | Type         | Null | Key | Default | Extra          |
+-------------+--------------+------+-----+---------+----------------+
| id          | bigint       | NO   | PRI | NULL    | auto_increment |
| name        | varchar(200) | YES  |     | NULL    |                |
| create_date | datetime(6)  | NO   |     | NULL    |                |
| customer_id | bigint       | NO   | MUL | NULL    |                |
+-------------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)

Python 框架学习 Django篇 (六) 数据表关联、ORM关联-LMLPHP

2、一对一

 vi Django_demo/paas/models.py

class Student(models.Model):
    # 姓名
    name = models.CharField(max_length=200)
    # 班级
    classname = models.CharField(max_length=200)
    # 描述
    desc = models.CharField(max_length=200)


class ContactAddress(models.Model):
    # 一对一 对应学生 
    student = models.OneToOneField(Student, on_delete=models.PROTECT)
    # 家庭
    homeaddress = models.CharField(max_length=200)
    # 电话号码
    phone = models.CharField(max_length=200)

 3、多对多

 Python 框架学习 Django篇 (六) 数据表关联、ORM关联-LMLPHP

 vi Django_demo/paas/models.py

import datetime
class Order(models.Model):
    # 订单名
    name = models.CharField(max_length=200,null=True,blank=True)

    # 创建日期
    create_date = models.DateTimeField(default=datetime.datetime.now)

    # 客户
    customer = models.ForeignKey(Customer,on_delete=models.PROTECT)

    # 订单购买的药品,和Medicine表是多对多 的关系
    medicines = models.ManyToManyField(Medicine, through='OrderMedicine')

python manage.py makemigrations
python manage.py migrate 

#查看
desc paas_OrderMedicine;

 Python 框架学习 Django篇 (六) 数据表关联、ORM关联-LMLPHP

4、管理药品实现

vi Django_demo/mgr/medicine.py

from django.http import JsonResponse

# 导入 Medicine 对象定义(这块可能显示模块导入不正常,忽略)
from  paas.models import  Medicine

import json

def Orderdispatcher(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_medicine':
        return listmedicine(request)
    elif action == 'add_medicine':
        return addmedicine(request)
    elif action == 'modify_medicine':
        return modifymedicine(request)
    elif action == 'del_medicine':
        return deletemedicine(request)

    else:
        return JsonResponse({'ret': 1, 'msg': '不支持该类型http请求'})



def listmedicine(request):
    # 返回一个 QuerySet 对象 ,包含所有的表记录
    qs = Medicine.objects.values()

    # 将 QuerySet 对象 转化为 list 类型
    # 否则不能 被 转化为 JSON 字符串
    retlist = list(qs)

    return JsonResponse({'ret': 0, 'retlist': retlist})


def addmedicine(request):

    info    = request.params['data']

    # 从请求消息中 获取要添加客户的信息
    # 并且插入到数据库中
    medicine = Medicine.objects.create(name=info['name'] ,
                                       sn=info['sn'] ,
                                       desc=info['desc'])


    return JsonResponse({'ret': 0, 'id':medicine.id})


def modifymedicine(request):

    # 从请求消息中 获取修改客户的信息
    # 找到该客户,并且进行修改操作

    medicineid = request.params['id']
    newdata    = request.params['newdata']

    try:
        # 根据 id 从数据库中找到相应的客户记录
        medicine = Medicine.objects.get(id=medicineid)
    except Medicine.DoesNotExist:
        return  {
            'ret': 1,
            'msg': f'id 为`{medicineid}`的药品不存在'
        }


    if 'name' in  newdata:
        medicine.name = newdata['name']
    if 'sn' in  newdata:
        medicine.sn = newdata['sn']
    if 'desc' in  newdata:
        medicine.desc = newdata['desc']

    # 注意,一定要执行save才能将修改信息保存到数据库
    medicine.save()

    return JsonResponse({'ret': 0})


def deletemedicine(request):

    medicineid = request.params['id']

    try:
        # 根据 id 从数据库中找到相应的药品记录
        medicine = Medicine.objects.get(id=medicineid)
    except Medicine.DoesNotExist:
        return  {
            'ret': 1,
            'msg': f'id 为`{medicineid}`的客户不存在'
        }

    # delete 方法就将该记录从数据库中删除了
    medicine.delete()

    return JsonResponse({'ret': 0})




添加路由

vi Django_demo/mgr/urls.py

from django.urls import path

from .k8s import dispatcher
from .sign_in_out import signin,signout

from .medicine import orderdispatcher  #添加
urlpatterns = [
    path('customers/', dispatcher),
    path('medicines/', orderdispatcher),  #添加 必须带斜杠

    path('signin', signin),
    path('signout', signout),


]

5、添加药品

vi main.py

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_medicine",
    "data":{
        "name":"板蓝根",
        "sn":"133",
        "desc":"感冒药"
    }
}
url='http://127.0.0.1:8000/api/mgr/medicines/'
if set_cookie:
    # 将Set-Cookie字段的值添加到请求头中
    headers = {'Cookie': set_cookie}

    # 发送请求给web服务
    response = requests.post(url,json=payload,headers=headers)
    pprint.pprint(response.json())

json类型说明

#data=payload  表示这个请求携带的参数是以表单的形式也就是字符串形式传输给后端的
requests.post(url,data=payload)


#json=payload   表示参数是以json的形式传输给后端的
requests.post(url,json=payload)

6、查询药品

vi main.py

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')
if set_cookie:
    # 将Set-Cookie字段的值添加到请求头中
    headers = {'Cookie': set_cookie}

    # 发送带有Cookie的新请求 修改url到新的路由
    response = requests.get('http://127.0.0.1:8000/api/mgr/medicines/?action=list_medicine',headers=headers)
    pprint.pprint(response.json())

返回

{'ret': 0,
 'retlist': [{'desc': '192.168.1.2', 'id': 1, 'name': 'abc', 'sn': '133'},
             {'desc': '感冒药', 'id': 2, 'name': '板蓝根', 'sn': '133'}]}

遇到的问题

7、修改药品

vi main.py

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":"modify_medicine",
    "id": "1",
    "newdata":{
        "name":"诺氟沙星",
        "sn":"141",
        "desc":"无"
    }
}
url='http://127.0.0.1:8000/api/mgr/medicines/'

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': [{'desc': '无', 'id': 1, 'name': '诺氟沙星', 'sn': '141'},
             {'desc': '感冒药', 'id': 2, 'name': '板蓝根', 'sn': '133'}]}

8、删除药品

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":"del_medicine",
    "id":"1",
}
url='http://127.0.0.1:8000/api/mgr/medicines/'

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': [{'desc': '感冒药', 'id': 2, 'name': '板蓝根', 'sn': '133'}]}

二、数据库关联操作

1、一对多

#先查询用户的id,然后基于id查询外键对应的订单
select * from paas_order where customer_id = (select id from paas_customer where name = "zhangsan");

2、多对多

二、ORM关联表、事务

10-25 07:33