博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django中ORM系统多表数据操作
阅读量:6214 次
发布时间:2019-06-21

本文共 18324 字,大约阅读时间需要 61 分钟。

一,多表操作之增删改查

1.在seting.py文件中配置数据库连接信息

2.创建数据库关联关系models.py

from django.db import models# Create your models here.class Book(models.Model):    title = models.CharField( max_length=32)    pub_date=models.DateField()    price=models.DecimalField(max_digits=5,decimal_places=2)   #以book表为基本表创建与出版社表的关联关系关联字段publish_id Django会自动拼接_id    publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE,null=True)   #以book表为基本表创建通过与第三方表book2author与author表的多对多关联关系,    authors=models.ManyToManyField("Author",db_table="book2authors") # 创建关系表    def __str__(self):        return self.titleclass Publish(models.Model):    name=models.CharField( max_length=32)    city=models.CharField( max_length=32)    email=models.CharField(max_length=32)    def __str__(self):        return self.nameclass Author(models.Model):    name=models.CharField( max_length=32)    age=models.IntegerField()    #books=models.ManyToManyField("Book")   #以author表为基本表通过创建ad字段关联AuthorDetail作者详情表的一对一的关联关系    ad=models.OneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE)    def __str__(self):        return self.nameclass AuthorDetail(models.Model):    birthday=models.DateField()    telephone=models.BigIntegerField()    addr=models.CharField( max_length=64)    # author=models.OneToOneField("Author",on_delete=models.CASCADE)    def __str__(self):        return str(self.telephone)'''class book_authors(models.Model):    book=models.ForeignKey("Book",on_delete=models.CASCADE)    author=models.ForeignKey("Author",on_delete=models.CASCADE)'''class Emp(models.Model):    name=models.CharField(max_length=32)    age=models.IntegerField()    salary=models.DecimalField(max_digits=8,decimal_places=2)    dep=models.CharField(max_length=32)    province=models.CharField(max_length=32)class Article(models.Model):    title=models.CharField(max_length=32)    comment_num=models.IntegerField()    poll_num=models.IntegerField()    def __str__(self):return self.title

3 在启动函数时,在项目文件setiing.py文件中配置相应的库

4 在url分发器中配置网页与视图函数的映射关系

5 在视图函数views.py中封装对数据库操作的功能,

from django.shortcuts import render,HttpResponse,redirect# Create your views here.from app01 import modelsdef add(request):    ################################## 绑定一对多关系 ##############################    # 方式1:    #book=models.Book.objects.create(title="linux",price=122,pub_date="2012-12-12",publish_id=1)    # 方式2:    # pub_obj=models.Publish.objects.filter(name="橘子出版社").first()    # book=models.Book.objects.create(title="php",price=122,pub_date="2012-12-12",publish=pub_obj)    # print(book.title)    # print(book.publish_id)    # print(book.publish) # book书籍出版社对象    # 查询go出版社的邮箱    # models.Publish.objects.filter(id= book.publish_id).first().email    # book.publish.email    ########################## 绑定多对多的关系;无非是在关系表创建记录 ##########    # linux这本书绑定两个作者:alex,egon    # linux=models.Book.objects.filter(title="linux").first()    # alex=models.Author.objects.filter(name="alex").first()    # egon=models.Author.objects.filter(name="egon").first()    # print(linux.price)    # print(linux.publish)    #linux.authors.add(alex,egon)    #linux.authors.add(1)    #linux.authors.add(*[1,2])    #linux.authors.remove(alex,egon)    #linux.authors.clear()    #linux.authors.set([1,])    '''    #KEY:关联属性:authors    class Book(models.Model):            title = models.CharField( max_length=32)            pub_date=models.DateField()            price=models.DecimalField(max_digits=5,decimal_places=2)            publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE,null=True)            authors=models.ManyToManyField("Author",db_table="book2authors") # 创建关系表            def __str__(self):                return self.title    '''    ###############    # 正向操作按字段,反向操作按表名小写    linux = models.Book.objects.filter(title="linux").first()    go = models.Book.objects.filter(title="go").first()    alex = models.Author.objects.filter(name="alex").first()    # 给alex作者绑定两本书籍: linux,go    alex.book_set.add(linux,go)    return HttpResponse("添加成功!")def query(request):    '''    一 基于对象的跨表查询( 子查询:以上一次的查询结果作为下一次的查询条件)       (1)一对多                         正向查询:按字段 book.publish         Book对象    ---------------------------------- >  Publish 对象                      <---------------------------------                        反向查询:按表名小写_set.all()        (2)多对多                       正向查询:按字段 book.authors.all()         Book对象    ---------------------------------- >  Author 对象                      <---------------------------------                        反向查询:按表名小写_set.all()        (2)一对一                        正向查询:按字段 book.ad         Author 对象   ---------------------------------- >  AuthorDetail 对象                      <---------------------------------                        反向查询:按表名小写    二 基于双下划綫的跨表查询:       KEY:通知ORM引擎如何跨表: 正向查询按字段,反向查询按表名小写    :param request:    :return:    '''    重点1############一基于对象的跨表查询#######################    #(1)一对多    # 1 查询linux这本书籍的出版社的地址    # book=models.Book.objects.filter(title="linux").first()    # print(book.publish.city)    # 2 查询苹果出版社出版的所有书籍    # publish=models.Publish.objects.filter(name="苹果出版社").first()    # queryset=publish.book_set.all()    # print(queryset) # 
,
]> # (2)多对多 # 1 查询linux书籍的所有作者 # linux=models.Book.objects.filter(title="linux").first() # queryset=linux.authors.all() #
]> # print(queryset) # 2 查询alex作者出版过得所有书籍 # alex=models.Author.objects.filter(name="alex").first() # queryset=alex.book_set.all() # print(queryset) #
,
]> # (3)一对一 # 1 查询alex的手机号 # alex = models.Author.objects.filter(name="alex").first() # print(alex.ad.telephone) # 2 查询手机号为911的作者的名字 # ad=models.AuthorDetail.objects.filter(telephone=911).first() # print(ad.author.name) 重点2###基于双下划线的跨表查询(join查询)################################# # 1 查询linux这本书籍的出版社的地址 ''' SELECT app01_publish.city from app01_book INNER JOIN app01_publish ON app01_book.publish_id = app01_publish.id WHERE app01_book.title ="linux" ''' # 方式1 # queryset=models .Book.objects.filter(title="linux").values("price","publish__city") # print(queryset) # # 方式2 # queryset=models.Publish.objects.filter(book__title="linux").values("city") # print(queryset) # 2 查询linux书籍的所有作者 #queryset=models.Book.objects.filter(title="linux").values("authors__name") #queryset=models.Book.objects.filter(title__startswith="l").values("authors__name") # ******** #print(queryset) #
# queryset=models.Author.objects.filter(book__title="linux").values("name") # 3 查询alex的手机号 # queryset=models.Author.objects.filter(name="alex").values("ad__telephone") # queryset=models.AuthorDetail.objects.filter(author__name="alex").values("telephone") # print(queryset) #
# 重点3 连续跨表 # 4 查询人民出版社出版过的所有书籍的名字以及作者的姓名 # queryset=models.Book.objects.filter(publish__name="人民出版社").values("title","authors__name") # models.Author.objects.filter(book__publish__name="人民出版社").values("book__title","name") # 5 手机号以151开头的作者出版过的所有书籍名称以及出版社名称 queryset=models.Book.objects.filter(authors__ad__telephone__contains="1").values("title","publish__name") print(queryset) return HttpResponse("查询成功!")
重点4:###################### 分组查询 #####################################    # 单表分组查询    #queryset=models.Emp.objects.all() # select * from emp    # queryset=models.Emp.objects.values("name") # select name from emp;    # print(queryset)    '''    单表分组查询:    #查询每一个部门名称以及对应的员工数        sql:        select dep,Count(*) from emp group by dep;                select dep,AVG(salary) from emp group by dep;            orm:        queryset=models.Emp.objects.values("dep").annotate(c=Count("*"))    '''    from django.db.models import Avg,Count,Max,Min    # 查询每一个部门的人数   #  queryset=models.Emp.objects.values("dep").annotate(c=Count("*"))   #  print(queryset)  # 
# # # 查询每一个省份的平均薪水 # queryset=models.Emp.objects.values("province").annotate(avg_salary=Avg("salary")) # print(queryset) #
############### 多表分组查询 # 1 查询每一个出版社的名字和出版过的书籍的平均价格 ''' -- sql语句: SELECT app01_publish.name,AVG(app01_book.price) from app01_book LEFT JOIN app01_publish on app01_book.publish_id = app01_publish.id group by app01_publish.id,app01_publish.name ''' # queryset=models.Publish.objects.values("id","name").annotate(avg_price=Avg("book__price")) # queryset=models.Publish.objects.values("id","name","email","city").annotate(avg_price=Avg("book__price"))    #打印结果 # [{"id":1,"name":"苹果出版社","eamil":"123","city":"beijing",'avg_price': 119.0},   {"id":1,"name":"橘子出版社","eamil":"123","city":"beijing",'avg_price': 155.333333.0}] # queryset=models.Publish.objects.all().annotate(avg_price=Avg("book__price")) # print(queryset) #
,
]> # for obj in queryset: # print(obj.name,obj.avg_price) # 2 查询每一个作者的名字以及出版书籍的个数 queryset=models.Author.objects.annotate(c=Count("book")).values("name","c") print(queryset) #
# 3 查询每一个书籍的名称以及作者的个数 queryset=models.Book.objects.annotate(c=Count("authors")).values("title","c") print(queryset) # 4 查询作者个数大于1 的每一本书籍的名称和作者个数 queryset=models.Book.objects.annotate(c=Count("authors")).filter(c__gt=1).values("title","c") print(queryset) #
# 5 查询书籍名称包含"h"的书籍名称和作者个数 queryset=models.Book.objects.filter(title__contains="h").annotate(c=Count("authors")).values("title","c") 重点5############# F查询与Q查询 # F查询 from django.db.models import F,Q,Avg # 1 查询评论数大于100的文章 # queryset=models.Article.objects.filter(comment_num__gt=100) # print(queryset) # 2 查询评论数大于点赞数的文章 # queryset=models.Article.objects.filter(comment_num__gt=F("poll_num")) # print(queryset) #
]> # 3 查询点赞数大于两倍评论数 # queryset=models.Article.objects.filter(poll_num__gt=F("comment_num")*2) # print(queryset) #
]> # 4 将所有的书籍的价格提高100元 # models.Book.objects.all().update(price=F("price")+100) # Q查询 # 5 查询价格大于300或者名称以p开头的书籍 # Q : & | ~ # queryset=models.Book.objects.filter(Q(title__startswith="p")&Q(price__gt=300)) # print(queryset) #
,
,
]> # # 5 查询价格大于300或者不是2019年一月份的书籍 # lq=Q(price__gt=300)|~Q(Q(pub_date__year=2019)&Q(pub_date__month=1)) queryset = models.Book.objects.filter(q) # print(queryset)

6 刷新网页来测试数据库相关功能

实例1ORM 多表关联图书管理系统

第一步 创建项目,先创建模型对数据库进行操作     并配置数据库信息 1 创建表
from django.db import models# Create your models here.class Book(models.Model):    title = models.CharField( max_length=32)    pub_date=models.DateField()    price=models.DecimalField(max_digits=5,decimal_places=2)    #以Book表为基本表创建与Publish表的外键关联关系关联字段publish_id Django自动拼接_id,on_delete=models.CASCADE:级联删除    publish=models.ForeignKey(to="Publish",to_field="id",on_delete=models.CASCADE,null=True)    #以Book表为基本表创建第三方表book2authors与Author表建立多对多的关联关系    authors=models.ManyToManyField("Author",db_table="book2authors") # 创建关系表    def __str__(self):        return self.titleclass Publish(models.Model):    name=models.CharField( max_length=32)    city=models.CharField( max_length=32)    email=models.CharField(max_length=32)    def __str__(self):        return self.nameclass Author(models.Model):    name=models.CharField( max_length=32)    age=models.IntegerField()    #books=models.ManyToManyField("Book")    #以作者表Author为基本表创建与作者详情表AuthorDetail的一对一的关联关系    ad=models.OneToOneField("AuthorDetail",null=True,on_delete=models.CASCADE)     def __str__(self):        return self.nameclass AuthorDetail(models.Model):    birthday=models.DateField()    telephone=models.BigIntegerField()    addr=models.CharField( max_length=64)    # author=models.OneToOneField("Author",on_delete=models.CASCADE)    def __str__(self):        return str(self.telephone)
models.py

   2 配置数据库信息

DATABASES = {    'default': {        'ENGINE': 'django.db.backends.mysql',        'NAME':'duo', # 要连接的数据库,连接前需要创建好        'USER':'root', # 连接数据库的用户名        'PASSWORD':'123', # 连接数据库的密码        'HOST':'127.0.0.1', # 连接主机,默认本级        'PORT':3306  #  端口 默认3306    },}
seting.py
3 启动项目:通过模型在目标数据库中创建相应的表,
#注意:在建表之前必须先创建好seting.py文件中mysql配置的库在建表之前要在url.py路由分发的同级目录下的启动文件__init__.py中导入import pymysqlpymysql.install_as_MySQLdb()然后在项目路径文件下执行以下命令在mysql中创建表python manage.py makemigrationspython manage.py migrate
引入pymysql
第二步 创建URL与该URL调用的视图函数之间的映射表
from django.contrib import adminfrom django.urls import path,re_pathfrom duo_books import viewsurlpatterns = [    path('admin/', admin.site.urls),    path('add/', views.add),    path('query/', views.query),    path('books/', views.books),    path('books/add/', views.addbook),    re_path('books/delete/(\d+)/', views.delbook),    re_path('books/edit/(\d+)/', views.editbook),
urls.py
第三步 创建视图函数中对数据的操作进行封装
def books(request):    queryset = models.Book.objects.all()    return render(request, "books.html", {
"queryset": queryset})def delbook(request, id): models.Book.objects.filter(pk=id).delete() return redirect("/books/")def addbook(request): if request.method == "POST": data = request.POST.dict() data.pop("csrfmiddlewaretoken") data.pop("author_list") book = models.Book.objects.create(**data) # 保证提交键值对的键必须和数据库表字段一致 # 为书籍绑定作者关系 author_list = request.POST.getlist("author_list") print(author_list) # ['1', '2'] book.authors.add(*author_list) return redirect("/books/") else: publish_list = models.Publish.objects.all() author_list = models.Author.objects.all() return render(request, 'addbook.html', locals())def editbook(request,edit_book_id): edit_book = models.Book.objects.filter(pk=edit_book_id).first() if request.method=="POST": # 方式1: # title=request.POST.get("title") # price=request.POST.get("price") # pub_date=request.POST.get("pub_date") # publish_id=request.POST.get("publish_id") # author_list=request.POST.getlist("author_list") # models.Book.objects.filter(pk=edit_book_id).update(title=title,price=price,pub_date=pub_date,publish_id=publish_id) # update只有queryset才能调用 # edit_book.authors.set(author_list) # 方式2: data=request.POST.dict() data.pop("csrfmiddlewaretoken") author_list=data.pop("author_list") models.Book.objects.filter(pk=edit_book_id).update(**data) # 保证提交键值对的键必须和数据库表字段一致 # 为书籍绑定作者关系 author_list=request.POST.getlist("author_list") edit_book.authors.set(author_list) return redirect("/books/") else: publish_list=models.Publish.objects.all() author_list=models.Author.objects.all() return render(request,'editbook.html',locals())
views.py
第四步 创建静态文件夹static放置Jquery,css,bootstrap样式文件 修改Django配置,完成对静态文件的配置
STATIC_URL = '/static/'STATICFILES_DIRS=[    os.path.join(BASE_DIR,"static") #  静态文件的物理路径]
seting.py

第五步 在模板文件夹template下建立相应的前端页面  添加功能页面
    
Title

添加书籍

{% csrf_token %}
addbook.html
查看功能页面(含删除功能)
    
Title

书籍列表

添加书籍
{% for book in queryset %}
{% endfor %}
ID 书籍名称 价格 出版社 出版日期 作者 操作
{ { forloop.counter }} { { book.title }} { { book.price }} { { book.publish }} { { book.pub_date|date:"Y/m/d" }} {% for author in book.authors.all %} { { author.name }} {% endfor %} 删除 编辑
books.html

   编辑功能的页面

    
Title

编辑书籍

{% csrf_token %}
editbook.html

 

转载于:https://www.cnblogs.com/liucsxiaoxiaobai/p/10220310.html

你可能感兴趣的文章
OSChina 周一乱弹 ——周日晚上,高跟鞋坏了。
查看>>
OSChina 周六乱弹 —— 看见这花臂了么?赶紧叫大佬!
查看>>
各种架构图
查看>>
[小脚本] bash维护并行下载任务
查看>>
SQL 左外连接,右外连接,内连接 | GRUP BY, HAVING
查看>>
redis单机安装
查看>>
普通java项目打jar包运行
查看>>
ABBYY FineReader 12中怎样自定义主窗口
查看>>
使用 highlight.js 高亮网站代码
查看>>
笨兔兔的故事——带你了解Ubuntu,了解Linux 第二章 醒来
查看>>
spark sql简单示例
查看>>
CSRF防范简介
查看>>
关于HTTP keep-alive的实验
查看>>
前嗅ForeSpider脚本教程:字段取值脚本
查看>>
分析NTFS文件系统内部结构
查看>>
android程序加载so动态库和jar包
查看>>
nagios插件性能数据显示格式
查看>>
创建临时表的语法
查看>>
数学相关
查看>>
深入理解Magento – 第三章 – 布局,块和模板
查看>>