c语言sscanf函数的用法是什么
237
2022-09-23
django -- ORM实现作者增删改查
前戏
前面我们已经实现了出版社的增删改查,书的增删改查,书和出版社的对应关系。现在来写一下作者的增删改查和书的对应关系,那书和作者有什么关系呢?一个作者可以写多本书,一本书可以有多个作者,所以书和作者是多对多的关系,这样的话,我们就需要一张表来记录书和作者的关系,想一下sql语句是怎么创建表的
-- 创建作者表create table author( id int primary key auto_increment, name varchar(32) not null );
-- 创建作者和书的关系表create table author2book( id int primary key auto_increment, author_id int not null, book_id int not null, constraint fk_author foreign key (author_id) references author(id) on delete cascade on update cascade, constraint fk_book foreign key (book_id) references book(id) on delete cascade on update cascade );
ORM创建表
使用上面的SQL语句创建表是不是很麻烦,那我们使用ORM创建表怎么创建呢?这里有两种方法
第一种:自己创建作者表和第三张关系表
# 作者表class Author(models.Model): id = models.AutoField(primary_key=True) # 自增id主键 name= models.CharField(max_length=32) # 作者名字# 创建作者和书籍的关系class Author2Book(models.Model): id = models.AutoField(primary_key=True) author = models.ForeignKey(to='Author', on_delete=models.CASCADE) book = models.ForeignKey(to='Book', on_delete=models.CASCADE)
第二种:让ORM帮我们创建第三张关系表
# 作者表class Author(models.Model): id = models.AutoField(primary_key=True) # 自增id主键 name= models.CharField(max_length=32) # 作者名字 books = models.ManyToManyField('Book') # ManyToManyField自动帮我们创建第三张表,只是ORM层面建立的一个多对多的关系,不存在于Author表中
def __str__(self): return self.name
books这个字段不会出现在Author表和Book表里,会另外创建一张表来存两者之间的关系,所以写在Author表或Book表里都可以,如果写在Book表里,里面就要写Author了
我们使用第二种方法来创建数据表,因为如果我们要查作者和书的关系时,第二种方法对象.books就可以查到
执行完生成数据表的命令后,查看数据库,发现ORM自动给我们生成了第三张表,我们在两张数据表里添加一些数
用ORM查询
先来看一下数据表里的数据
作者表
作者和书的对应关系表
书表
添加路由
url(r'^author_list/', views.author_list), # 作者列表
添加对应函数
def author_list(request): # 查询到所有的作者 author_data = Author.objects.all() return render(request, 'author_list.html', {'author_list': author_data})
这里需要说明的是author_data是所有作者的对象,
print(author_data) #
我们去循环author_data
def author_list(request): # 查询到所有的作者 author_data = Author.objects.all() print(author_data) #
结果
在取添加author_list.html
序号 | 作者id | 作者姓名 | 作者作品 |
---|---|---|---|
{{ forloop.counter }} | {{ author.id }} | {{ author.name }} | {% for book in author.books.all %} {% if forloop.last %} 《{{ book.title }}》 {% else %} 《{{ book.title }}》, {% endif %} {% empty %} 暂无作品 {% endfor %} |
代码解释:
{% for book in author.books.all %} 在前面我们知道 author.books.all()取出来的是一个对象,因为一个作者可能有多个书,所以我们循环这个对象
{% empty %}也是for循环里的,当循环出的book是一个空对象时,执行下面的代码”暂无作品“
{% if forloop.last %}表示循环到最后一个执行下面的代码
添加作者
获取作者的功能已经实现了,那我们在写个添加作者的功能,添加作者,还要选择书,所以这里涉及了两张表,第一张是author表,第二张是author和book对应关系的那张表,先去添加路由
url(r'^add_author/', views.add_author), # 添加作者
在去添加对应的函数
# 添加作者def add_author(request): book_data = Book.objects.all() return render(request, 'add_author.html', {"book_list": book_data})
添加add_author.html文件
因为一个作者可以有多本书,所以书籍是多选的,在去修改对应的函数
# 添加作者def add_author(request): if request.method == 'POST': new_author_name = request.POST.get('author_name') # 这个只能取到一个值 book_ids = request.POST.getlist('books') # 这个取多个值,取到的是一个列表 author_obj = Author.objects.create(name=new_author_name) #创建新的作者 # author_obj.books.add(*book_ids) # 参数是一个一个单独的书籍id值,打散传进去 author_obj.books.set(book_ids) # 参数是书籍id值的列表 return redirect('/author_list/') book_data = Book.objects.all() return render(request, 'add_author.html', {"book_list": book_data})
因为书籍是多选的,所以可能有多个书的id,所以要用到request.POST.getlist('books')
author_obj = Author.objects.create(name=new_author_name) 返回的值是作者的名字
author_obj.books.add(*book_ids)因为只能一个一个接收参数,所以这里需要打散,记得前面要加上表名
a = [1, 2, 3]print(*a)结果:1 2 3
打散
author_obj.books.set(book_ids)接收的是一个列表,和上面的效果是一样的
删除作者
添加路由
url(r'^delete_author/', views.delete_author), # 删除作者
添加对应的函数
# 删除作者def delete_author(request): delete_author_id = request.GET.get('id') Author.objects.get(id=delete_author_id).delete() return redirect('/author_list/')
html文件只需要更改下author_list.html里的代码即可
编辑作者
添加路由
url(r'^edit_author/', views.edit_author), # 编辑作者
添加对应的函数
# 编辑作者def edit_author(request): edit_author_id = request.GET.get('id') # 取到要编辑的作者id # edit_author_obj = Author.objects.get(id=edit_author_id) # 取到要编辑的作者对象 edit_author_obj = Author.objects.filter(id=edit_author_id)[0] # 取到要编辑的作者对象 if request.method == 'POST': new_book_ids = request.POST.getlist('book_ids') new_author_name = request.POST.get('author_name') edit_author_obj.name = new_author_name edit_author_obj.save() edit_author_obj.books.set(new_book_ids) # 修改作者和书的关系表 return redirect('/author_list/') book_data = Book.objects.all() return render(request, 'edit_author.html', {'author': edit_author_obj, 'book_list': book_data})
说明:
edit_author_obj.books.set(new_book_ids)意思是将这个作者和书的对应关系去掉,然后重新设置对应关系
添加edit_author.html文件
代码解释
{% if book in author.books.all %} 这里的book是book这个表里的一项,在判断这一项在没在书和作者对应关系的那张表里,如果在,则设置成默认选中的
上传文件
上传文件需要在html文件里的form表单里指定 enctype="multipart/form-data"。这样Django才能正常接收文件
添加路由
url(r'^upload/', views.upload), # 上传文件
添加对应函数
# 上传文件def upload(request): if request.method == 'POST': file_obj = request.FILES.get('file_name') # 获取文件 file_name = file_obj.name # 取到文件名+后缀 # 从上传文件对象里一点一点读取数据,写到本地 with open(file_name, 'wb') as f: for line in file_obj: f.write(line) return render(request, 'upload.html')
说明:之前获取提交的数据用的是request.POST.get或者request.GET.get,但是获取文件信息要用request.FILES.get,返回的也是一个字典,key是input输入框里的name属性
添加对应的html文件
改版:
导入settings.py文件
from django.conf import
如果文件存在,重命名
# 上传文件def upload(request): if request.method == 'POST': file_obj = request.FILES.get('file_name') # 获取文件 file_name = file_obj.name # 取到文件名+后缀 # 判断文件是否存在 if os.path.exists(os.path.join(settings.BASE_DIR, file_name)): # 如果存在同名的文件 name,suffix = file_name.split('.') name += '1' file_name = name + '.'+ suffix # 从上传文件对象里一点一点读取数据,写到本地 with open(file_name, 'wb') as f: for line in file_obj: f.write(line) return render(request, 'upload.html')
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~