Python 框架学习 Django篇 (六) 数据表关联_django orm 的 __ 链表,使用什么链接方式 (1)

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Python全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img



既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Python知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024c (备注Python)
img

正文

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

#查看
desc paas_customer;

**现在我们要生成订单表,按照实际情况我们订单表的字段里面也会有客户的信息表示谁下的订单,而用户的信息需要使用外键去关联客户的主键,而客户表也就是customer表的主键就是id字段,**Django中定义外键 的方法就是 Model类的该属性字段 值为(ForeignKey)

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)

上面定义的customer是外键,让他去找Customer表的主键获取数据,而这里设置了一个on_delete的参数,这个意思是当主键被删除了那么外键这个数据还要不要了

1、CASCADE: 跟随主机一起把外键数据删除

2、PROTECT   禁止删除,如果非要删除就先清除外键数据后,才能删除对应主键

3、SET_NULL   删除后外键数据修改为null

注意

外键字段,实际在数据库表中的字段名是DjangoForeignKey定义字段名加上后缀"_id"

比如上面,在执行了 migrate 命令更新数据库后,customer 这个外键字段实际上在 数据库表中的字段名 是 customer_id

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)

2、一对一

上面的外键案例,可以说是一对多或者多对一,而有时候是一对一的情况

比如,某个学校的学生表 和学生的地址表,就形成一对一的关系,即 一条主键所在表的记录 只能对应一条 外键所在表的记录,而Django 中 用 OneToOneField 对象 实现 一对一 的关系

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)

Django发现这样一对一定定义,它会在migrate的时候,在数据库中定义该字段为外键的同时, 加上 unique=True 约束,表示在此表中,所有记录的该字段 取值必须唯一,不能重复

3、多对多

数据库中还存在一种多对多的关系,在order订单表中

一个订单可以采购多种药品,就对应 Medicine表里面的多种药品;

而一种药品也可以被多个订单采购, 那么Order表 和 Medicine表 之间就形成了多对多的关系

Django是通过 ManyToManyField 对象 表示 多对多的关系的

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')

class OrderMedicine(models.Model):
    #添加外键
    order = models.ForeignKey(Order, on_delete=models.PROTECT)
    medicine = models.ForeignKey(Medicine, on_delete=models.PROTECT)

    # 订单中药品的数量  一种特殊的类型,表示非负整数
    amount = models.PositiveIntegerField()  

我们上面通过medicines = models.ManyToManyField(Medicine, through=‘OrderMedicine’)

去指定Order表和Medicine表的对应关系,其实不会在Order表上面创建medicines的字段

python manage.py makemigrations
python manage.py migrate 

#查看
desc paas_OrderMedicine;

4、管理药品实现

我们在 mgr 目录下面新建 medicine.py,处理 客户端发过来的 列出药品、添加药品、修改药品、删除药品 的请求,需要运用前面的数据库增删改查的方法

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'}]}

第一行是我写错了添加上的,一会当作删除的案例

遇到的问题

在访问url的时候,要确定url访问时是否需要带上/  如果定义的urls上有/,那边必须要带上斜杠不然会报错

做了那么多年开发,自学了很多门编程语言,我很明白学习资源对于学一门新语言的重要性,这些年也收藏了不少的Python干货,对我来说这些东西确实已经用不到了,但对于准备自学Python的人来说,或许它就是一个宝藏,可以给你省去很多的时间和精力。

别在网上瞎学了,我最近也做了一些资源的更新,只要你是我的粉丝,这期福利你都可拿走。

我先来介绍一下这些东西怎么用,文末抱走。


(1)Python所有方向的学习路线(新版)

这是我花了几天的时间去把Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。

最近我才对这些路线做了一下新的更新,知识体系更全面了。

在这里插入图片描述

(2)Python学习视频

包含了Python入门、爬虫、数据分析和web开发的学习视频,总共100多个,虽然没有那么全面,但是对于入门来说是没问题的,学完这些之后,你可以按照我上面的学习路线去网上找其他的知识资源进行进阶。

在这里插入图片描述

(3)100多个练手项目

我们在看视频学习的时候,不能光动眼动脑不动手,比较科学的学习方法是在理解之后运用它们,这时候练手项目就很适合了,只是里面的项目比较多,水平也是参差不齐,大家可以挑自己能做的项目去练练。

在这里插入图片描述

(4)200多本电子书

这些年我也收藏了很多电子书,大概200多本,有时候带实体书不方便的话,我就会去打开电子书看看,书籍可不一定比视频教程差,尤其是权威的技术书籍。

基本上主流的和经典的都有,这里我就不放图了,版权问题,个人看看是没有问题的。

(5)Python知识点汇总

知识点汇总有点像学习路线,但与学习路线不同的点就在于,知识点汇总更为细致,里面包含了对具体知识点的简单说明,而我们的学习路线则更为抽象和简单,只是为了方便大家只是某个领域你应该学习哪些技术栈。

在这里插入图片描述

(6)其他资料

还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/bfb82d64421c368fc2d3db1cb08109a0.png)

(6)其他资料

还有其他的一些东西,比如说我自己出的Python入门图文类教程,没有电脑的时候用手机也可以学习知识,学会了理论之后再去敲代码实践验证,还有Python中文版的库资料、MySQL和HTML标签大全等等,这些都是可以送给粉丝们的东西。

在这里插入图片描述

这些都不是什么非常值钱的东西,但对于没有资源或者资源不是很好的学习者来说确实很不错,你要是用得到的话都可以直接抱走,关注过我的人都知道,这些都是可以拿到的。

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024c (备注python)
[外链图片转存中…(img-hKdjWhgp-1713342422605)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 27
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值