tips
1,关于注释掉settings文件里的一行代码,Django的保护机制(它认可的请求会接收),不认可浏览器提交的post请求会拒绝掉,注释此行代码,就不会拒绝post请求.(粗略写)
django.middleware.csrf.CsrfViewMiddleware
2,关于__str__与__repr__的使用,(了解)
代码示例
class Animal(): s1=\'hhh\' s2=\'HHH\' def __init__(self,name,age): self.name=name self.age=age def __str__(self): return self.name def __repr__(self): return self.age dog=Animal(\'阿黄\',1) print(dog) # 输出:只输出阿黄,
当有__str__的时候,就会先执行,__str__,没有的话会执行__repr__,还没有会去父类找,结合代码,print()的输出有变化,就是__str__的结果,__repr__是关于内置的,
/
/
bootstrap的引入模版,
div. 按tab键直接出来:<div class=""></div>
图书管理系统表结构的设计
外键
在之前的基础上(3,的基础上)继续写,在models里面写book的表,
设置图书表跟出版社表的外键,
先叙述出版社跟书的关系,结合数据库之前的知识来学习
class Book(models.Model): #下面的一行代码可以不写(id开头这行),django会给添加,如果要更改id名字比如改成name_id,可以再写 id=models.AutoField(primary_key=True) title=models.CharField(max_length=32,unique=True)
#下面的这一行代码,是设置外键的,(书跟出版社之间的),to后跟要关联的表, publisher_id=models.ForeignKey(to=Publisher,on_delete=models.CASCADE)#Django2.0之前,后面的on_delete=models.CASCADE不用写,2.0之后接得写了,
外键的设置 to
关于反射
未进行反射折射之前,如果class Book之前,代码会报错,因为找不到Publisher,
class Publisher(models.Model): id=models.AutoField(primary_key=True) name=models.CharField(max_length=32,unique=True)#自己默认不能为空, def __str__(self): return self.name class Book(models.Model): #下面的一行代码可以不写,django会给添加,如果要更改id名字比如改成name_id,可以再写 id=models.AutoField(primary_key=True) title=models.CharField(max_length=32,unique=True) publisher_id=models.ForeignKey(to=Publisher,on_delete=models.CASCADE)
设置to=\'Publisher\'之后,类的顺序
class Book(models.Model): #下面的一行代码可以不写,django会给添加,如果要更改id名字比如改成name_id,可以再写 id=models.AutoField(primary_key=True) title=models.CharField(max_length=32,unique=True) publisher_id=models.ForeignKey(to=\'Publisher\',on_delete=models.CASCADE) class Publisher(models.Model): id=models.AutoField(primary_key=True) name=models.CharField(max_length=32,unique=True)#自己默认不能为空, def __str__(self): return self.name
另外,设置的外键的时候,django会自动在外键后面加_id,所以外键命名的时候可以不写_id,针对上面的代码,
执行数据库迁移命令,
/
也可以写成:to=\'Publisher\',字符串形式
设置作者表表之后,添加外键关系,数据库里多了一张表,
/
接下来进行书籍的增删改查
/
/
/
展示书籍:
注意,此处的book.publisher是直接拿到了publisher对象,
<td>{{ book.publisher }}</td>
views的代码
def book_list(requset): books=models.Book.objects.all() return render(requset,\'book_list.html\',{\'books\':books})
html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>书籍列表</title> </head> <body> <h1>书籍列表</h1> <table border="1"> <thead> <tr> <th>序号</th> <th>ID</th> <th>书名</th> <th>出版社</th> </tr> </thead> <tbody> {% for book in books %} <tr> <td>{{ forloop.counter }}</td> <td>{{ book.id }}</td> <td>{{ book.title }}</td> <td>{{ book.publisher }}</td> </tr> {% endfor %} </tbody> </table> </body> </html>
/
/
数据库迁移时,执行两条命令的出错情况,
有一个django_migrations表,跟操作记录,还有数据库的内容要一致,
增加书籍:
views代码
def add_book(request): #获取form表单提交的数据 if request.method==\'POST\': book_name=request.POST.get(\'book_name\') pub_id=request.POST.get(\'pub_id\') # pub_obj=models.Publisher.objects.get(id=pub_id) # models.Book.objects.create(title=book_name,publisher=pub_obj) #下面一行代码与上面两行代码的功能是一样的, models.Book.objects.create(title=book_name,publisher_id=pub_id) return redirect(\'/book_list/\') # 获取所有出版社信息 publisher_list=models.Publisher.objects.all() return render(request,\'add_book.html\',{\'publisher_list\':publisher_list})
其中,等价代码,
pub_obj=models.Publisher.objects.get(id=pub_id) models.Book.objects.create(title=book_name,publisher=pub_obj) 下面一行代码与上面两行代码的功能是一样的, models.Book.objects.create(title=book_name,publisher_id=pub_id)
templates文件的,html代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>添加书籍</title> </head> <body> <h1>添加书籍</h1> <form action="" method="post"> <div> 书名: <input type="text" name="book_name"> </div> <div> 出版社: <select name="pub_id" id=""> {% for pub in publisher_list %} <option value="{{ pub.id }}">{{ pub.name}}</option> {% endfor %} </select> </div> <button>提交</button> </form> </body> </html>
删除书籍
views代码
def del_book(request): del_id=request.GET.get(\'book_id\') print(del_id) #删除获取到的id对应的数据, models.Book.objects.get(id=del_id).delete() return redirect(\'/book_list/\')
编辑书籍
<option value="pub.id">{{ pub.name }}</option>,value是向服务器发送的值,
views代码
# 书籍的编辑 def edit_book(request): if request.method == \'POST\': old_id=request.POST.get(\'old_id\') new_title = request.POST.get(\'new_title\') pub_id = request.POST.get(\'pub_id\') old_obj=models.Book.objects.get(id=old_id) old_obj.title=new_title old_obj.publisher_id=pub_id # 上面一行代码与下面的一行代码是等价的, # old_obj.publisher=models.Publisher.objects.get(id=pub_id) old_obj.save() return redirect(\'/book_list/\') edit_id=request.GET.get(\'id\') edit_obj=models.Book.objects.get(id=edit_id) all_pub=models.Publisher.objects.all() return render(request,\'edit_book.html\',{\'edit_obj\':edit_obj,\'all_pub\':all_pub})
html代码,
{%if%}
{%endif%}的使用,
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>编辑书籍</title> </head> <body> <h1>编辑书籍</h1> <form action="" method="post"> <input type="text" name="old_id" value="{{ edit_obj.id }}" style="display: none"> <div> 书名: <input type="text" name="new_title" value="{{ edit_obj.title }}" > </div> <div> 出版社: <select name="pub_id" id=""> {% for pub in all_pub %} {% if pub.id == edit_obj.publisher_id %} <option selected value="{{ pub.id }}">{{ pub.name }}</option> {% else %} <option value="{{ pub.id}}">{{ pub.name }}</option> {% endif %} {% endfor %} </select> </div> <button>提交</button> </form> </body> </html>
多对多,作者表的介入
作者表的创建,django建的第四张表,作者与书籍的关系,
1,多对多 :
ManyToManyField(Book)
class Author(models.Model): name=models.CharField(max_length=32,unique=True) books=models.ManyToManyField(Book)
自动创建的第四张表,作者与书的关系
/
/
在{{}}里面,没有加括号的操作
<td>{{ author.books.all}}</td>
作者列表的展示
html代码:
for book in author author.books.all
author.books.all:是一个对象列表,queryset
boos:是一个个书籍对象,
/
/
<tbody> {% for author in author_list %} <tr> <td>{{ forloop.counter }}</td> <td>{{ author.id }}</td> <td>{{ author.name }}</td> <td> {% for book in author.books.all %} {{ book.title }} {% endfor %} </td> </tr> {% endfor %} </tbody>
修改后的代码的演示
{% for book in author.books.all %}
{% if forloop.last %} # 判断是不是最后一次循环,是的话,就不加顿号(或者进行别的替换)
《{{ book.title }}》
{% else %}
《{{ book.title }}》、 # 不是最后一次循环,就按一下格式进行替换
{% endif %}
{% endfor %}
views代码
def author_list(request): # 获取所有的作者 author_list=models.Author.objects.all() return render(request,\'author_list.html\',{\'author_list\':author_list})
增加作者
getlist使用
def add_author(request): if request.method==\'POST\': author_name=request.POST.get(\'author_name\') book_ids=request.POST.getlist(\'book_ids\') print(request.POST)
#输出:<QueryDict: {\'author_name\': [\'作者的名字\'], \'book_ids\': [\'2\', \'4\']}> print(author_name)
#输出:作者的名字 print(book_ids)
#输出:[\'2\', \'4\']
views的代码
set的使用
#增加作者
def add_author(request):
if request.method==\'POST\':
author_name=request.POST.get(\'author_name\')
book_ids=request.POST.getlist(\'book_ids\')
# 把作者名字添加到数据库,返回一个作者对象
author_obj=models.Author.objects.create(name=author_name)
#author_obj.books拿到一个(多对多)管理对象,建立作者跟书的关系
author_obj.books.set(book_ids)
return redirect(\'/author_list/\')
book_list=models.Book.objects.all()
return render(request,\'add_author.html\',{\'book_list\':book_list})
/
/
html代码
<form action="" method="post"> <div> 作者的名字: <input type="text" name="author_name"> </div> <div> 作品: <select name="book_ids" id="" multiple> {% for book in book_list %} <option value="{{ book.id }}">{{ book.title }}</option> {% endfor %} </select> </div> <button>提交</button> </form>
/
/
作者的删除
views代码
delete:把多对多的关系也给删除了,html代码是直接在author_list文件里添加按钮(a标签),
#删除作者 def del_author(request): # 1,获取到作者对象 del_id=del_id=request.GET.get(\'id\') # 2,在数据库中删除作者的数据 # 3,删除多对多 关系的记录 models.Author.objects.get(id=del_id).delete() return redirect(\'/author_list/\')
作者的编辑
html代码
<div> 著作: <select name="book_ids" id="" multiple> {% for book in all_books %} {% if book in edit_obj.books.all %} <option value="{{ book.id }}" selected>{{ book.title }}</option> {% else %} <option value="{{ book.id }}">{{ book.title }}</option> {% endif %} {% endfor %} </select> </div>
day68 1. 内容回顾 1. django目前学到的所有命令 pip install django==1.11.15 django-admin startproject 项目名 cd 项目目录下 python manage.py runserver # 127.0.0.1:8000 python manage.py runserver 80 # 127.0.0.1:80 python manage.py runserver 0.0.0.0:80 # 0.0.0.0:80 python manage.py startapp app名称 python manage.py makemigrations # 检查你的app下的models.py是否有变化 有变更将记录到app下的migrations文件夹下 python manage.py migrate # 把变更记录更新到数据中 2. settings.py 中的配置 1. 注释csrf中间件 form可以提交POST请求 2. 静态文件 STATIC_URL = \'/static/\' # 别名 STATICFILES_DIRS = [ os.path.join(BASE_DIR,\'static\'), os.path.join(BASE_DIR,\'static1\'), os.path.join(BASE_DIR,\'static2\'), ] 3. 数据库的配置 ENGINE: 引擎 mysql NAME: 数据库名称 USER: 用户名 PASSWORD: 密码 HOST: IP PORT: 端口 3306 4. INSTALLED_APPS = [ \'app01\' , \'app01.apps.App01Config\' ] 5. TEMPLATES DIRS os.path.join(BASE_DIR,\'templates\') 3. GET POST GET 在浏览器地址栏上输入URL 回车 点击a标签 form表单不写method 127.0.0.1:8000/add_publisher/?id=1&name=alex POST form表单指定method=\'post\' 数据不可见 4. django使用mysql数据库的流程 1. 创建一个mysql数据库 2. 在settings中配置mysql DATABASES = { \'default\': { \'ENGINE\': \'django.db.backends.mysql\', \'NAME\': \'library\', \'USER\': \'root\', \'PASSWORD\': \'\', \'HOST\': \'127.0.0.1\', \'PORT\': 3306, } } 3. 在和settings.py同级目录下__init__.py写代码: import pymsql pymsql.install_as_MySQLdb() 4. 在app01/models.py中写类(继承models.Model) class Publisher(models.Model): id = models.AutoField(primary_key=True) name = models.CharField(max_length=32,unique=True) 5. 执行数据库迁移的命令 python manage.py makemigrations python manage.py migrate 5. ORM操作 from app01 import models 增: models.Publisher.objects.create(name=\'新华出版社\') 查: 查询所有 models.Publisher.objects.all() ——》 对象列表 获取一个对象 models.Publisher.objects.get(name=\'新华出版社\') ——》 单独的一个对象 获取满足条件的对象 models.Publisher.objects.filter(name=\'新华出版社\') ——》对象列表 删: models.Publisher.objects.filter(name=\'新华出版社\').delete() models.Publisher.objects.get(name=\'新华出版社\').delete() ret = models.Publisher.objects.all() ret[0].delete() 改: obj = models.Publisher.objects.get(name=\'新华出版社\') obj.name = \'新新华出版社\' obj.save() 6. 模板相关 render(request,\'模板名字\',{\'new_name\':\'新华出版社\',\'err_meg\':\'出版社已存在\'}) {{ 变量名 }} {{ new_name}} 新华出版社 标签 {% for publisher in publishers %} {{ forloop.counter }} {{ publisher.id }} {{ publisher.name }} {% endfor%} 2. 今日内容 1. 图书管理系统的表结构设计 出版社 书 作者 出版社 书 一对多 书 作者 多对多 2. 外键 描述 多对一的关系 写在多的一方 class Book(models.Model): title = models.CharField(max_length=32, unique=True) publisher = models.ForeignKey(to=Publisher, on_delete=models.CASCADE) # publisher = models.ForeignKey(to=\'Publisher\', on_delete=models.CASCADE) book_obj.publisher ——》 书籍关联的对象 book_obj.publisher_id ——》 书籍关联的对象id 直接从数据库获取的 # 设置外键(关联出版社对象) 修改 book_obj.publisher = 出版社对象 book_obj.save() book_obj.publisher_id = 1 book_obj.save() # 创建 models.Book.objects.create(title=\'新的书名\',publisher=models.Publisher.objects.get(id=1)) models.Book.objects.create(title=\'新的书名\',publisher_id=1) 3. 多对多 书 和 作者 class Author(models.Model): name = models.CharField(max_length=32, unique=True) books = models.ManyToManyField(\'Book\') author_obj.books ——》 不是关联的对象 是管理的对象 author_obj.books.all() ——》 获取到跟作者关联的所有书籍对象 author_obj.books.set([1,2,3,4]) ——》不是author_obj.save() author_obj.books.set([1,2]) author_obj.books.set([3,4]) getlist #获取的是列表 4. 模板相关 if判断 {% if book in edit_obj.books.all %} <option value="{{ book.id }}" selected>{{ book.title }}</option> {% else %} <option value="{{ book.id }}">{{ book.title }}</option> {% endif %} {% if 条件1 %} 操作1 {% elif 条件2 %} 操作2 {% else %} 操作3 {% endif %} for循环中 {% for i in name_list %} {{ forloop.first }} 第一次循环 {{ forloop.last }} 最后一次循环 {% endfor %} 3. 作业 1. 课上代码 + bootstrap样式 2. 学生管理系统 三个model 学生 老师 班级 三张表的增删改查