• Django 之多对多关系


    1. 多对多关系

    作者 <--> 书籍
    1. 表结构设计
    1. 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
    );

    2. ORM版

    1. 第一版:

    自己创建第三张表

    2. 第二版

    让ORM帮我们创建第三张表
    models.ManyToManyField()

    3. 第三版

    待补充...(ORM进阶操作的时候)

    2. 作者的增删改查

    1. 查询

    # 展示作者
    def author_list(request):
        # 1. 去数据库查询到所有的作者
        author_data = Author.objects.all()
        for author in author_data:
            print(author)
            # 取到每个作者出版的书籍
            # print(author.books)  # 是一个ORM提供的桥梁(工具),帮我找对应关系
            print(author.books.all())
        # 2. 在页面上展示出来
        return render(request, 'author_list.html', {'author_list': author_data})

    author_obj.books --> 得到的只是一个关联关系,并不能拿到数据
    author_obj.books.all() --> 得到和我这个作者关联的所有书籍对象列表

    2. 添加

    1. add()

    # 添加作者
    def add_author(request):
        if request.method == 'POST':
            # 1. 取到用户填写的信息
            new_author_name = request.POST.get('author_name')
            # book_ids = request.POST.get('books')  # -->这个只能取到一个值
            book_ids = request.POST.getlist('books')
            # print(new_author_name)
            # print(book_ids)
            print(request.POST.getlist('hobby'))
            print('-' * 120)
            # 2. 添加到数据库
            # 2.1 创建新的作者
            author_obj = Author.objects.create(name=new_author_name)
            # 2.2 创建新作者和书的对应关系
            author_obj.books.add(*book_ids)  # 参数是一个一个单独的书籍id值
            # author_obj.books.set(book_ids)  # 参数是书籍id值的列表
            # 3. 跳转到作者列表页面
            return redirect('/author_list/')
        # 1. 返回一个页面给用户,让用户填写作者信息
        # 2. 获取所有的书籍信息
        book_data = Book.objects.all()
        return render(request, 'add_author.html', {'book_list': book_data})

    3. 删除

    # 删除作者
    def delete_author(request):
        # 1. 取到要删除的作者的id值
        delete_author_id = request.GET.get('kangchen')
        age = request.GET.get('age')
        print(delete_author_id)
        print(age)
        # 2. 同过id找到数据,并删除
        Author.objects.filter(id=delete_author_id).delete()
        # 3. 让用户再访问作者列表页面
        return redirect('/author_list/')

     

    4. 编辑

    # 编辑作者
    def edit_author(request):
        # 1. 取到要编辑的作者的id值
        edit_author_id = request.GET.get('id')
        # 2. 找到要编辑的作者对象
        edit_author_obj = Author.objects.get(id=edit_author_id)
    
        if request.method == 'POST':
            # 3. 拿到编辑之后的数据
            new_author_name = request.POST.get('author_name')
            new_book_ids = request.POST.getlist('book_ids')
            # 4. 去数据库修改
            # 4.1 修改作者表
            edit_author_obj.name = new_author_name
            edit_author_obj.save()
            # 4.2 修改作者和书的关系表
            edit_author_obj.books.set(new_book_ids)
            # 5. 跳转到作者列表页面
            return redirect('/author_list/')
    
        # 2.2 找到所有的书籍对象
        book_data = Book.objects.all()
        # 3. 返回一个页面
        return render(request, 'edit_author.html', {'author': edit_author_obj, 'book_list': book_data})

     

    1. 模板语言中

    {% if book in author.books.all %}

    2. ORM编辑多对多

    1. 不能直接操作第三张关系表
    2. 借助ORM给提供的方法

    •   all()
    •   add(id1,id2)
    •   set([id1, id2])
    •   clear()

    3. Django模板语言

    1. for循环

    1. forloop.last

    {% if forloop.last %}
    ...

    2. empty

    {% for i in x %}
    ...
    {% empty %}
    ...
    {% endfor %}

    4. 上传文件

    form表单上传文件

    views.py中

    # 上传文件
    def upload(request):
        if request.method == 'POST':
            # 1. 取到用户发送的数据
            print(request.POST)
            print(request.FILES)
            file_obj = request.FILES.get('file_name')
            print(file_obj.name)
            # 判断当前是否存在
            file_name = file_obj.name
            if os.path.exists(os.path.join(settings.BASE_DIR, file_name)):
                # 如果存在同名的文件
                name, suffix = file_name.split('.')
                name += '2'
                file_name = name + '.' + suffix
            # 从上传文件对象里 一点一点读取数据,写到本地
            with open(file_name, 'wb') as f:
                # 从上传文件对象里 一点一点读取数据
                for chunk in file_obj.chunks():
                    f.write(chunk)
        # 1. 第一次GET请求来,应该给用户返回一个页面,让用户选择文件
        return render(request, 'upload.html')

    html文件中

    <!DOCTYPE html>
    <html lang="zh-CN">
    <head>
        <meta http-equiv="content-Type" charset="UTF-8">
        <meta http-equiv="x-ua-compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>上传文件示例</title>
    </head>
    <body>
    
    
    <h1>上传文件</h1>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="text" name="test">
        <input type="file" name="file_name">
        <input type="submit">
    </form>
    
    </body>
    </html>
  • 相关阅读:
    ceph中pool的管理
    ubuntu 16.04安装ceph集群(双节点)
    win7设置开机启动virtualBOX虚拟机
    Linux Linux程序练习十九
    Linux Linux程序练习十八
    Linux Linux程序练习十七
    Linux 网络编程详解十二
    Linux socket多进程服务器框架三
    Linux socket多进程服务器框架二
    Linux socket多进程服务器框架一
  • 原文地址:https://www.cnblogs.com/wjs521/p/9804581.html
Copyright © 2020-2023  润新知