Django学习笔记
一、使用Anaconda安装Django运行环境
二、查看当前Django版本
python -m django --version
三、创建项目
-
新建文件夹Django-demo
-
pycharm工具打开文件夹(获取管理员权限)
-
使用pycharm工具的命令窗cd命令新建的文件夹
-
新建django项目demo1
-
django-admin startproject demo1
-
-
cd命令进入demo1,运行项目
-
python manage.py runserver 0.0.0.0:80
-
-
浏览器输入127.0.0.1查看项目是否运行
四、路由
-
进入demo1项目
-
# 创建项目app功能模块sales python manage.py startapp sales
-
# sales/views文件下创建网站访问返回函数listorders from django.http import HttpResponse def listorders(request): return HttpResponse("显示输出。。。")
-
给项目app添加子路由
-
# 在sales文件夹下新建子路由表urls.py from django.urls import path from . import views urlpatterns = [ path('orders/', views.listorders), ]
-
-
把子路由添加到主路由表
-
from django.contrib import admin from django.urls import path # 别忘了导入 listorders 函数 from sales.views import listorders urlpatterns = [ path('admin/', admin.site.urls), # 添加如下的路由记录 path('sales/orders/', listorders), ]
-
打开测试页 http://127.0.0.1/sales/orders/
-
查看返回数据
-
五、数据库
-
创建数据库
-
python manage.py migrate
-
使用sqllite工具打开数据库
-
-
自定义数据表单common
-
# 创建项目app python manage.py startapp common
-
# 添加表数据 from django.db import models class Customer(models.Model): # 客户名称 name = models.CharField(max_length=200) # 联系电话 phonenumber = models.CharField(max_length=200) # 地址 address = models.CharField(max_length=200)
-
# 创建数据库表 # 在项目的配置文件 settings.py 中, INSTALLED_APPS 配置项 加入如下内容 INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', # 加入下面这行 'common.apps.CommonConfig', ]
-
# 更新数据库脚本 python manage.py makemigrations common # 执行数据库操作代码 python manage.py migrate # 注意:如果以后我们修改了Models.py 里面的库表的定义,都需要再次运行 python manage.py makemigrations common 和 python manage.py migrate 命令,使数据库同步该修改结果
-
-
创建管理员
-
# 管理员账号创建 python manage.py createsuperuser
-
# 配置管理员文件 common/admin.py from django.contrib import admin from .models import Customer admin.site.register(Customer)
-
# setting.py文件下配置admin中文界面 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # admin界面语言本地化 'django.middleware.locale.LocaleMiddleware', ]
-
在用户表中添加数据
- 访问数据库地址
http://127.0.0.1/admin/
- 在customers中添加数据
- 填写完成后保存
- 在SQL软件中查看刚才添加的内容
- 访问数据库地址
-
-
查询数据库数据
-
获取全部
-
# 在sales/views.py中,定义一个listcustomers函数 # 导入 Customer 对象定义 from common.models import Customer def listcustomers(request): # 返回一个 QuerySet 对象 ,包含所有的表记录 # 每条表记录都是是一个dict对象, # key 是字段名,value 是 字段值 qs = Customer.objects.values() # 定义返回字符串 retStr = '' for customer in qs: for name,value in customer.items(): retStr += f'{name} : {value} | ' # <br> 表示换行 retStr += '<br>' return HttpResponse(retStr)
-
# 将功能添加到路由表中 path('customers/', views.listcustomers),
-
访问
http://127.0.0.1/sales/customers/
就可以获取listcustomers函数所返回的内容
-
-
过率条件
-
# 在sales/views.py中,定义一个listcustomers的条件函数 # 通过filter方法加入过滤条件 def listcustomers(request): # 返回一个 QuerySet 对象 ,包含所有的表记录 qs = Customer.objects.values() # 检查url中是否有参数phonenumber ph = request.GET.get('phonenumber',None) # 如果有,添加过滤条件 if ph: qs = qs.filter(phonenumber=ph) # 定义返回字符串 retStr = '' for customer in qs: for name,value in customer.items(): retStr += f'{name} : {value} | ' # <br> 表示换行 retStr += '<br>' return HttpResponse(retStr)
-
访问地址
http://127.0.0.1/sales/customers/?phonenumber=213
- 查看是否有phonenumber=213的数据,并显示出来
-
-
数据库的增删改查
-
创建mgr项目app
-
python manage.py startapp mgr
-
-
添加项目路由
-
# 新建一个程序 customer.py 来分配请求 from django.http import JsonResponse import json def dispatcher(request): # 将请求参数统一放入request 的 params 属性中,方便后续处理 # GET请求 参数在url中,同过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_customer': return listcustomers(request) elif action == 'add_customer': return addcustomer(request) elif action == 'modify_customer': return modifycustomer(request) elif action == 'del_customer': return deletecustomer(request) else: return JsonResponse({'ret': 1, 'msg': '不支持该类型http请求'})
-
总路由文件添加文件
-
# 凡是 url 以 api/mgr 开头的, # 都根据 mgr.urls 里面的 子路由表进行路由 path('api/mgr/', include('mgr.urls')),
-
-
子路由文件添加urls文件
-
from django.urls import path from mgr import customer urlpatterns = [ path('customers', customer.dispatcher), ]
-
-
-
关闭跨域校验
-
# 在 setting 中设置 MIDDLEWARE = [ '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', # admin界面语言本地化 'django.middleware.locale.LocaleMiddleware', ]
-
-
查询
-
# 导入 Customer from common.models import Customer def listcustomers(request): # 返回一个 QuerySet 对象 ,包含所有的表记录 qs = Customer.objects.values() # 将 QuerySet 对象 转化为 list 类型 # 否则不能 被 转化为 JSON 字符串 retlist = list(qs) return JsonResponse({'ret': 0, 'retlist': retlist})
-
-
增加
-
def addcustomer(request): info = request.params['data'] # 从请求消息中 获取要添加客户的信息 # 并且插入到数据库中 # 返回值 就是对应插入记录的对象 record = Customer.objects.create(name=info['name'] , phonenumber=info['phonenumber'] , address=info['address']) return JsonResponse({'ret': 0, 'id':record.id})
-
-
修改
-
def modifycustomer(request): # 从请求消息中 获取修改客户的信息 # 找到该客户,并且进行修改操作 customerid = request.params['id'] newdata = request.params['newdata'] try: # 根据 id 从数据库中找到相应的客户记录 customer = Customer.objects.get(id=customerid) except Customer.DoesNotExist: return { 'ret': 1, 'msg': f'id 为`{customerid}`的客户不存在' } if 'name' in newdata: customer.name = newdata['name'] if 'phonenumber' in newdata: customer.phonenumber = newdata['phonenumber'] if 'address' in newdata: customer.address = newdata['address'] # 注意,一定要执行save才能将修改信息保存到数据库 customer.save() return JsonResponse({'ret': 0})
-
-
删除
-
def deletecustomer(request): customerid = request.params['id'] try: # 根据 id 从数据库中找到相应的客户记录 customer = Customer.objects.get(id=customerid) except Customer.DoesNotExist: return { 'ret': 1, 'msg': f'id 为`{customerid}`的客户不存在' } # delete 方法就将该记录从数据库中删除了 customer.delete() return JsonResponse({'ret': 0})
-
-
-
-
和前端集成
-
将静态文件放在和项目APP相同文件夹下
-
修改urls
-
# 静态文件服务 from django.conf.urls.static import static # 在文件末尾添加 + static("/", document_root="./z_dist")
-
# 启动服务器 python manage.py runserver 80 # 打开测试网页 http://localhost/mgr/index.html
-
# 常见问题,发现页面是一片空白 # setting.py 中 末尾添加如下代码 import mimetypes mimetypes.add_type('text/css', '.css') mimetypes.add_type('application/javascript', '.js') # 然后,刷新网页(按ctrl键刷新,确保不用缓存)即可。
-
-
-
登录功能
-
# 在mgr项目下创建一个sign_in_out.py文件 from django.http import JsonResponse from django.contrib.auth import authenticate, login, logout # 登录处理 def signin( request): # 从 HTTP POST 请求中获取用户名、密码参数 userName = request.POST.get('username') passWord = request.POST.get('password') # 使用 Django auth 库里面的 方法校验用户名、密码 user = authenticate(username=userName, password=passWord) # 如果能找到用户,并且密码正确 if user is not None: if user.is_active: if user.is_superuser: login(request, user) # 在session中存入用户类型 request.session['usertype'] = 'mgr' return JsonResponse({'ret': 0}) else: return JsonResponse({'ret': 1, 'msg': '请使用管理员账户登录'}) else: return JsonResponse({'ret': 0, 'msg': '用户已经被禁用'}) # 否则就是用户名、密码有误 else: return JsonResponse({'ret': 1, 'msg': '用户名或者密码错误'}) # 登出处理 def signout( request): # 使用登出方法 logout(request) return JsonResponse({'ret': 0})
-
添加路由
-
from django.urls import path from mgr import sign_in_out urlpatterns = [ path('signin', sign_in_out.signin), path('signout', sign_in_out.signout), ]
-
访问
http://127.0.0.1/mgr/sign.html
-
输入数据库登录账号测试程序
-
-
-
数据库表的关联
-
一对多关系
-
# 在common的models模块中添加一张表 class Medicine(models.Model): # 药品名 name = models.CharField(max_length=200) # 药品编号 sn = models.CharField(max_length=200) # 描述 desc = models.CharField(max_length=200)
-
# 定义一个表Order,将表 Medicine 设置为其中一个字段 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)
-
-
一对一
-
# Django 中 用 OneToOneField 对象 实现 一对一 的关系 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是通过 ManyToManyField 对象 表示 多对多的关系的 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()
-
-
新增数据的相关API接口定义
-
#其中药品管理部分比较简单, 和前面的 customer.py 的代码 基本类似。 #我们在 mgr 目录下面新建 medicine.py,处理 客户端发过来的 列出药品、添加药品、修改药品、删除药品 的请求。 from django.http import JsonResponse # 导入 Medicine 对象定义 from common.models import Medicine import json def dispatcher(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})
-
# 在 mgr\urls.py 里面加上 对 medicine 的 请求处理 路由设置 from django.urls import path from mgr import customer,sign_in_out,medicine,order urlpatterns = [ path('customers', customer.dispatcher), path('medicines', medicine.dispatcher), # 加上这行 path('signin', sign_in_out.signin), path('signout', sign_in_out.signout), ]
-
-