day13-3django后端开发

一、配置

1.修改文件目录后,需要修改的位置

 

2.修改运行目录

 

3.复制db路径,重新连接数据库

 2.删除数据的操作步骤

https://blog.csdn.net/doulihang/article/details/102973565

3.数据库多对多的生成方式

django里面的多对多关系,它是通过建立第三张表来存储对应的关系。

在models模块

class Teacher(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'teacher'

class Student(models.Model):
    name = models.CharField(max_length=50,verbose_name='学生姓名')
    teacher = models.ManyToManyField(Teacher,verbose_name='老师')

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'student'

2.添加到admin中后,通过页面创建数据。查看数据库中的显示

#新增数据,新增多对多关系
#正向查询(在models里面有多对多的查询)
stu = models.Student.objects.create(name="fangdan")
stu.teacher.add(1)
stu.teacher.add(2)

# get_or_create如果存在就get,如果不存在就创建
stu,status = models.Student.objects.get_or_create(name="李想")
print(stu)
stu.teacher.remove(1)#从关系里面删除一个老师
print(stu.teacher.all())#查看所有老师
print(stu.teacher.get(id=2))


#反向查询,model里面没有多对多的这个字段
teacher,status = models.Teacher.objects.get_or_create(name= '大老师')
print(teacher.student_set.all())
# print(teacher.student_set.remove())
# print(teacher.student_set.add())
print(teacher.student_set.filter())
print(teacher.student_set.count())
# print(teacher.student_set.clear())
# print(teacher.student_set.create())

4.自关联

class Case(models.Model):
    name = models.CharField(max_length=50)
    url = models.CharField(max_length=10)
    method = models.CharField(max_length=20)
    param = models.CharField(max_length=30)
    #自关联,null=True数据不能为空,blank=True admin中不能为空
    require_case = models.ForeignKey('self',on_delete=models.PROTECT,verbose_name='依赖用例',null=True,blank=True)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'case'
        ordering = ['-id']

 5.一对一的关系

class Account(models.Model):
    balance = models.IntegerField(verbose_name='余额',default=0)

    class Meta:
        db_table = 'account'

class User(models.Model):
    name = models.CharField(max_length=50)
    account = models.OneToOneField(Account,on_delete=models.CASCADE,verbose_name='账户')#级联

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'user'

 6.数据库路由:不同的app访问不同的数据库

user访问sqllite,order访问的是mysql数据库

数据库配置:sqllite是文件数据库

pip install django_redis==4.10

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    },
    'mysql':{
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'jxz',
        'HOST': '118.24.3.40',
        'PASSWORD': '123456',
        'USER': 'jxz',
        'PORT': 3306,
    }
}#数据库配置

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://118.24.3.40:6379/0",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100},
            "PASSWORD": "HK139bc&*",  # 密码
        }
    },
    "redis2": {
        "BACKEND": "django_redis.cache.RedisCache",
        "LOCATION": "redis://118.24.3.40:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {"max_connections": 100, 'decode_responses': True},
            "PASSWORD": "HK139bc&*",  # 密码
        }
    }
}  # redis配置

DATABASE_ROUTERS = ['sky.database_router.DatabaseAppsRouter'] #与下面的类的路径

写一个数据库路由的类

db_mapper = {
    'sqlite':'default',
    'order':'mysql'

}

class DatabaseAppsRouter(object):
    def db_for_read(self, model, **hints):
        print('走了读',model)
        app_label = model._meta.app_label
        if app_label in db_mapper:
            return db_mapper[app_label]
        return 'default'

    def db_for_write(self, model, **hints):
        print('走了写',model)
        app_label = model._meta.app_label
        if app_label in db_mapper:
            return db_mapper[app_label]
        return 'default'

运行后django会报错,解决方法,是在sky的下面创建一个__init__.py,再启动就不会报错了

import pymysql
pymysql.install_as_MySQLdb()

在order中的models中写入

from django.db import models

# Create your models here.
class FDD(models.Model):
    name = models.CharField(max_length=50)

    def __str__(self):
        return self.name

    class Meta:
        db_table = 'Fdd'
        # app_label = 'new_user'因为是在order应用中写的,所以不用写这个


#makemigrations order
#migrate
# migrate order --database mysql

在mysql中插入数据报错,解决方法

    def allow_relation(self, obj1, obj2, **hints):
        '''允许两个表有关系'''
        return True

        # ValueError: Cannot
        # assign
        # "<ContentType: ContentType object (1)>": the
        # current
        # database
        # router
        # prevents
        # this
        # relation.

redis需要安装它 django_redis==4.10 

import django_redis
r = django_redis.get_redis_connectiong('redis2')
print(r.keys())

7.fvb,cvb(function(def) view,class view)

===参照user中的views 和order中的views的区别

8.urls拆分

order和user中的有views,在sky的urls中如果添加

方法一:使用别名as

from user import views
# from order import views as o_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('user.urls')),
    # path('user', o_view.UserView.as_view()),

]

方法二:拆分

分别在order和user中创建urls.py文件

from . import views

from django.urls import path

urlpatterns = [
    path('user',views.UserView.as_view(),),
]
order中的urls
from . import views

from django.urls import path
from .import views,new_views

urlpatterns = [
    path('index', views.index),
    # path('', views.get_sign),
    # path('category', views.category_view),
    path('category/<int:id>', views.category),
    path('detail/<int:id>', views.article),
    path('test', views.test),
    path('', views.index),
    path('add', views.add_article),
    path('interface', new_views.InterfaceView.as_view()),

]
user/urls.py
from django.contrib import admin
from django.urls import path,include
from user import views
# from order import views as o_view

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('user.urls')),
    path('order/',include('order.urls')),

]
sky/urls

9.中间件:类似上下文管理器

使用场景:总计应用中那个功能用的比较多,统计abc功能被用户用了多少次

 配置中间件:特别像抓包工具

 

 

 代码

from django.middleware.common import MiddlewareMixin
from django.shortcuts import HttpResponse
import django_redis
from user.models import Interface

class TestMiddleWare(MiddlewareMixin):
    def process_request(self,request):请求到这里
        print('process_request')
        # token = request.Get.get('token')
        # if token:
        #     r = django_redis.get_redis_connection()
        #     if r.get(token):
        #         pass
        #     else:
        #         return HttpResponse('请登录')

        path = request.path_info.replace('/','',1)
        interface = Interface.objects.filter(url=path)
        if interface:
            interface = interface.first()
            return HttpResponse(interface.response)

    def process_response(self,request,response):在views里处理完了请求,到这里
        print('process_response')
        return response

    def process_exception(self,request,exception):请求出错了,到这里
        return HttpResponse("系统开小差了~")
from django.shortcuts import render,HttpResponse

# Create your views here.
from django.views import View


class UserView(View):
    def get(self,request):
        print('走到了order的views')
        return HttpResponse('POST请求')

    def get(self,request):
        return HttpResponse('GET请求')

urls

from . import views

from django.urls import path

urlpatterns = [
    path('user',views.UserView.as_view(),),
]

请求http://127.0.0.1:8000/order/user

 

 

 

 中间的请求顺序

实践,在models中创建表,在admin中添加,然后添加内容

class Interface(models.Model):
    name = models.CharField(max_length=50)
    url = models.CharField(max_length=50,unique=True)
    response = models.TextField(default='{}',null=True,blank=True,verbose_name='返回报文')


    def __str__(self):
        return self.name

    class Meta:
        db_table = 'interface'

在浏览器中输入:http://127.0.0.1:8000/pay

注意:如果在数据库中已经创建好了,只是使用,但是在models里面又没有,解决方法:

inspectdb 数据库名 --database mysql

 

 

 导入到自己py文件中

    python manage.py makemigrations  app
    python manage.py migrate  app --database db
    python manage.py inspectdb table1 table2 table3 > models.py --database db

 10.接口查询

(1)基本接口

在new_views中

from django.core.paginator import Paginator
from django.forms import model_to_dict
from django.views import View
from django.shortcuts import HttpResponse
from django.http.response import JsonResponse
from .import models
import json
from common.response import SkyResponse
from common.const import page_limit
from django.db.models import Q


class InterfaceView(View):
    def get(self,request):
        return HttpResponse(
            json.dumps({"code":0,"msg":"操作成功"},ensure_ascii=False)
        )

在urls中

from .import views,new_views
urlpatterns = [
    path('index', views.index),
    path('interface', new_views.InterfaceView.as_view()),

]

结果:

 

 

 (2)增删改查

一个url,和多个url

字典:from django.forms import model_to_dict在sky中创建common文件,然后创建一个response.py

(3)查询所有
from django.http.response import JsonResponse

def SkyResponse(code=0,msg='操作成功',**kwargs):
    data = {'code':code,'msg':msg}
    data.update(**kwargs)
    return JsonResponse(data,json_dumps_params={'ensure_ascii':False} )
#查询所有的
from common.response import SkyResponse
    def get(self,request):
        l = []
        interface_query_set = models.Interface.objects.all()
        for d in interface_query_set:
            dic = model_to_dict(d)
            l.append(dic)

        return SkyResponse(data=l)

(3)按照id来筛选或者查询所有

    filter_field = ['id','name']
    @property
    def get_filter_dict(self):
        filter_dict = {}
        # {id:1,name:lhy}
        for field in self.filter_field:
            value = self.request.GET.get(field)
            if value:
                filter_dict[field] = value
        return filter_dict


    def get(self, request):
        # get 一条?id=1 筛选
        l = []
        interface_query_set = models.Interface.objects.filter(**self.get_filter_dict)

        for d in interface_query_set:
            dic = model_to_dict(d)
            l.append(dic)

        return SkyResponse(data=l)

(4)模糊查询:contains和Q

from django.db.models import Q

    search_field = ['name','url','request']

    @property
    def get_search_obj(self):
        q_obj = Q()
        search = self.request.GET.get('search')
        if search:
            for field in self.search_field:
                d = {'%s__contains' % field: search}
                q_obj = q_obj | Q(**d)
        return q_obj
    # models.Interface.objects.filter(Q(url__contains=seacher)|Q(name__contains=seacher)|Q(request__contains=seacher))

# 'select * from interface where url like 'aa' or name like 'aa' or response like 'aa';

    def get(self, request):
        # get 模糊查询 name=登
        l = []
    #先精确后模糊 interface_query_set
= models.Interface.objects.filter(**self.get_filter_dict).filter(self.get_search_obj) for d in interface_query_set: dic = model_to_dict(d) l.append(dic) return SkyResponse(data=l)

 

 

(5)分页

在sky的common中创建const.py

page_limit = 2 #默认分页数量

在new_views中

from common.const import page_limit

from django.core.paginator import Paginator分页

   def get_page_data(self,obj_list):
        try:
            limit = int(self.request.GET.get('limit',page_limit)) #limit = s
            page = int(self.request.GET.get('page',1))#默认获取第一页
        except:
            limit = page_limit
            page = 1
        page_obj = Paginator(obj_list,limit)
        result = page_obj.get_page(page)#分好页的数据
        return page_obj,result #page=1,limit=10

    def get(self, request):
        # 分页
        l = []
        page_obj, page_data = self.get_page_data(interface_query_set)
     interface_query_set = models.Interface.objects.filter(**self.get_filter_dict).filter(self.get_search_obj)
for d in page_data:
            dic = model_to_dict(d)
            l.append(dic)

        return SkyResponse(data=l, count=page_obj.count)

在网页中输入:http://127.0.0.1/interface?page=1&limit=2

 

 

11.接口删除

#删除
        def delete(self, request):
            id = request.GET.get('id')
            if id:
                query_set = self.model_class.objects.filter(id=id)
                if query_set:
                    query_set.delete()
                    return SkyResponse()
                else:
                    return SkyResponse(code=404, msg='id不存在')
            else:
                return SkyResponse(code=-1, msg='请传入id')

 

 问题解决:

在执行模糊搜索的时候,提示系统开小差了

然后去中间件中打印

 

 在postman中执行http://127.0.0.1:8000/interface?search=a的时候,提示错误信息

在pycharm中查看

 

 发现原来是自己的内容写错了,修改后好了

posted on 2020-12-06 10:08  轻微强迫症  阅读(161)  评论(0编辑  收藏  举报