• Django项目之图书管理系统


    Django——图书管理系统

    一、前期准备

    1、创建好 Django 项目

    2、准备好数据库 —— 创建数据库:book_system

    3、配置项目中的数据库引擎

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'book_system',
            'HOST': '127.0.0.1',
            'USER': 'root',
            'PASSWORD': 'root'
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、配置静态文件的搜索路径 , 以及在项目的根目录中创建一个 static 存放静态文件数据文件夹

    STATIC_URL = '/static/'
    STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]
    
    • 1
    • 2

    5、导入 html 模板文件和静态文件数据。

    二、用户注册

    1、响应用户注册页面的视图

    # 路由
    # 用户注册视图路由
    path('register/' , views.RegisterView.as_view()),
    
    
    # 响应视图
    class RegisterView(View):
        '''
        用户注册页面视图
        '''
        def get(self , request):
            # 响应注册页面
            return render(request , 'register.html')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、定义用户数据模型类 , 保存用户注册的个人数据信息

    class User(models.Model):
        '''
        保存用户注册数据
        '''
        username = models.CharField(max_length=20)
        password = models.IntegerField()
        email = models.EmailField()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、设置后端对用户注册数据进行验证 , 在对应的应用下创建一个 forms 的模块 , 实现数据验证

    class RegisterForm(forms.Form):
        '''
        验证用户注册数据
        '''
        username = forms.CharField(min_length=3 , max_length=15,
                                   error_messages={
                                       'min_length':'用户名长度不足',
                                       'max_length':'用户名长度超出',
                                       'required':'用户名不允许为空',
                                   })
        password = forms.CharField(min_length=6 , max_length=15,
                                   error_messages={
                                       'min_length':'密码长度不足',
                                       'max_length':'密码长度超出',
                                       'required':'密码不允许为空',
                                   })
        resetpw = forms.CharField(min_length=6 , max_length=15,
                                   error_messages={
                                       'min_length':'密码长度不足',
                                       'max_length':'密码长度超出',
                                       'required':'密码不允许为空',
                                   })
        email = forms.EmailField(error_messages={'invalid':'邮箱格式不正确',
                                                 'required':'邮箱不允许为空'})
    
        def clean(self):
            pwd1 = self.cleaned_data.get('password')
            pwd2 = self.cleaned_data.get('resetpw')
            if pwd1 != pwd2:
                self.add_error('resetpw' , '两次密码输入不一致')
    
            return self.cleaned_data
    
        def clean_username(self):
            name = self.cleaned_data.get('username')
            if not re.match(r'^[a-zA-Z0-9_]{3,15}$' , name):
                self.add_error('username' , '用户名格式不正确')
            return name
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    4、在注册视图中接收用户注册传递的数据 , 进行数据验证

    class RegisterView(View):
        '''
        用户注册页面视图
        '''
        def get(self , request):
            # 响应注册页面
            return render(request , 'register.html')
    
        def post(self , request):
            # 接收用户注册输入的数据
            # 传递给 forms 组件进行数据验证
            register_form = RegisterForm(request.POST)
            # 判断 forms 组件是否返回异常信息
            if register_form.is_valid():
                # 说明数据合法 没有异常 , 将用户数据保存到数据库中
                # 用户数据要从 forms 组件中取
                username = register_form.cleaned_data.get('username')
                password = register_form.cleaned_data.get('password')
                email = register_form.cleaned_data.get('email')
                return HttpResponse('用户数据正常')
            else:
                # 用户数据不合法 , 将异常信息返回到前端页面中
                return render(request , 'register.html' , locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    当用户数据异常不合法的情况下 ,后端将异常请求返回到前端 。在 html 页面中获取后端的异常数据信息

    <div class="form-group">
        <i class="fa fa-user" aria-hidden="true">i>
        用户名:<input class="form-control required" type="text" name="username" id="username" placeholder="请输入用户名" required>
        <span style="color:red;">{{ register_form.username.errors.0 }}span>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5、实现图片验证码 , 进行验证用户输入的验证码 ,验证码正确数据保存到数据库中,注册成功;否则用户注册失败。

    实现图片验证码的代码,直接使用之前写的。

    在当前应用下创建包 —— ImageCode

    实现验证码的视图

    # 路由
    # 图片验证码
    path('image_code/' , views.CodeImg),
    
    # 视图
    def CodeImg(request):
        # 响应图片验证码视图
        # 获取图片验证码以及验证码数据
        image , text = create_img()
        # session 会话
        # 将验证码数据保存到 session 会话中 , 以键值对的方式保存
        request.session['code'] = text
        # 将图片响应到出现
        return HttpResponse(image , content_type='image/png')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在注册是模板中添加验证码的文本框

    <div class="form-group">
        <i class="fa fa-envelope" aria-hidden="true">i>
        验证码:<input class="form-control required" type="text" name="img_code" id="img_code" placeholder="请输入验证码">
        <img src="/image_code/">
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    6、前端数据校验 , 使用 vue 的框架进行数据校验

    在标签中绑定数据信息 ,以及对文本框绑定对应的方法

    <div class="form-group">
        <i class="fa fa-user" aria-hidden="true">i>
        用户名:<input class="form-control required" type="text" name="username" id="username" placeholder="请输入用户名"
                   required v-model="username" @blur="check_name">
        <span style="color:red;">{{ register_form.username.errors.0 }}span>
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    校验用户名是否重复的视图

    # 路由
    # 检验用户名是否重复
    re_path('count/(?P[a-zA-Z0-9_ ]{3,15})/' , views.username_count),
    
    # 视图
    def username_count(request , username):
        # 从数据库获取用户数据
        count = User.objects.filter(username=username).count()
        return JsonResponse({'code':200 , 'errmsg':"OK" , 'count':count})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在静态文件中创建 register.js 文件

    let vm = new Vue({
        el:'#app',
    
        delimiters: ['[[' , ']]'],
    
        data:{
            username:'',
            password:'',
            resetpw:'',
            image_code_url:'',
    
            error_name:false,
            error_password:false,
            error_resetpw:false,
    
            error_name_message:'',
        },
    
        // 这个方法在 html 页面执行的时候 , 会被自动调用
        mounted(){
            this.image_code();
        },
    
        methods:{
            // 生成图片验证码
            image_code(){
                // 短时间内路由一致的情况下,会无法响应成功
                // 添加时间参数,保证在短时间内请求的路由不一致
                this.image_code_url = '/image_code/?'+ new Date().getTime()
            },
    
            // 验证用户名
            check_name(){
                // 定义用户名的规则范围
                let re = /^[a-zA-Z0-9_]{3,15}$/;
                // 判断用户名是否满足定义的规则
                if(re.test(this.username)){
                    // 用户名合法
                    this.error_name = false;
                } else {
                    // 用户名不合法
                    this.error_name = true;
                    this.error_name_message = '用户名不合法';
                }
                // 判断用户名是否重复
                // 前提保证用户名合法
                if(this.error_name == false){
                    // 发送 ajax 请求
                    axios.get(
                        '/count/'+this.username+'/',
                        {responseType:'json'}
                    )
                        // 请求成功
                        .then(response => {
                            if(response.data.count > 0){
                                // 用户已存在
                                this.error_name = true;
                                this.error_name_message = '用户名已存在';
                            } else {
                                this.error_name = false;
                            }
                        })
                        // 请求失败
                        .catch(error => {
                            console.log(error.response)
                        })
                }
            },
    
            // 校验密码
            check_password(){
                let re = /^[a-zA-Z0-9_]{6,15}$/;
                if(re.test(this.password)){
                    // 密码字符合法
                    this.error_password = false;
                } else {
                    // 密码字符不合法
                    this.error_password = true;
                }
            },
    
            // 校验两次密码是否一致
            check_resetpw(){
                if(this.password == this.resetpw){
                    this.error_resetpw = false;
                } else {
                    this.error_resetpw = true;
                }
            },
    
            // 表单是否允许提交的方法
            on_submit(){
                // 调用所有绑定的方法
                this.check_name();
                this.check_password();
                this.check_resetpw();
                // 判断 error 对应的值是否为 true , 如果其中有一个为 true 则不允许提交
                if(this.error_name == true || this.error_password == true || this.error_resetpw == true){
                    // 数据问题 , 禁止表单提交
                    window.event.returnValue = false;
                }
            }
        }
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104

    修改 图片验证码的 html 标签

    <div class="form-group">
        <i class="fa fa-envelope" aria-hidden="true">i>
        验证码:<input class="form-control required" type="img_code" name="img_code" id="img_code" placeholder="请输入验证码">
        <img v-bind:src="image_code_url" class="img_code" @click="image_code">
    div>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    7、在注册视图中 , 实现图片验证码的校验 , 验证码校验正确,用户数据保存到数据库中,用户注册成功;否则注册失败。

    class RegisterView(View):
        '''
        用户注册页面视图
        '''
        def get(self , request):
            # 响应注册页面
            return render(request , 'register.html')
    
        def post(self , request):
            # 接收用户注册输入的数据
            # 传递给 forms 组件进行数据验证
            register_form = RegisterForm(request.POST)
            # 判断 forms 组件是否返回异常信息
            if register_form.is_valid():
                # 说明数据合法 没有异常 , 将用户数据保存到数据库中
                # 用户数据要从 forms 组件中取
                username = register_form.cleaned_data.get('username')
                password = register_form.cleaned_data.get('password')
                email = register_form.cleaned_data.get('email')
    
                # 校验验证码 , 获取用户数输入的验证码
                img_code = request.POST.get('img_code')
                # 从 session 会话中获取保存的验证码
                code = request.session['code']
                if img_code == code:
                    # 验证码正确 , 将用户拒数据保存到数据库中,用户注册成功
                    User.objects.create(username=username , password=password , email=email)
                    # 注册成功重定向首页
                    return redirect('/index/')
                else:
                    # 验证码错误
                    return render(request , 'register.html' , {'code_error':'验证码错误'})
            else:
                # 用户数据不合法 , 将异常信息返回到前端页面中
                return render(request , 'register.html' , locals())
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    8、实现首页

    # 网站首页
    path('index/' , views.index),
    
    def index(request):
        # 响应首页
        return render(request , 'index.html')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    三、用户登录

    响应登录页面数据 , 接收用户登录的数据。

    # 用户登录
    path('login/' , views.LoginView.as_view()),
    
    class LoginView(View):
        '''
        用户登录视图
        '''
        def get(self , request):
            return render(request , 'login.html')
    
        def post(self , request):
            # 校验用户输入的数据
            login_form = LoginForm(request.POST)
            if login_form.is_valid():
                username = login_form.cleaned_data.get('username')
                password = login_form.cleaned_data.get('password')
                # 到数据库中进行查询用户数据是否存在
                user = User.objects.filter(username=username , password=password)
                if user:
                    # 用户登录成功
                    return redirect('/index/')
                else:
                    return render(request, 'login.html', {'errormsg': '账号或者密码错误'})
            else:
                return render(request , 'login.html' , {'errormsg':'账号或者密码错误'})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    四、出版社信息

    1、 定义出版社模型类

    class PublishingHouse(models.Model):
        '''
        出版社信息模型类
        '''
        # 出版社名称
        name = models.CharField(max_length=20)
        # 出版社类型
        publisher_type = models.CharField(max_length=15)
        # 出版社成立时间
        create_time = models.DateField()
        # 出版社位置
        address = models.CharField(max_length=30)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、设置出版社模板页面

    {% block main%}
    <table border="1" class="table table-hover table-bordered">
        <thead>
            <tr>
                <td>序号td>
                <td>出版社名称td>
                <td>出版社类型td>
                <td>出版社成立时间td>
                <td>出版社地址td>
                <td>操作td>
            tr>
        thead>
        <tbody>
            {% for foo in publisher %}
                <tr>
                    <td>{{ foo.id }}td>
                    <td>{{ foo.name }}td>
                    <td>{{ foo.publisher_type }}td>
                    <td>{{ foo.create_time }}td>
                    <td>{{ foo.address }}td>
                    <td>
                        <a href="#">修改a>
                        <a href="#">删除a>
                    td>
                tr>
            {% endfor %}
        tbody>
    table>
    {% endblock %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    3、 响应视图

    # 出版社列表响应
    path('publisher_list/' , views.publisher_list),
    
    # 视图
    def publisher_list(request):
        # 响应出版社列表
        # 从数据库中获取出版社的所有信息
        publisher = PublishingHouse.objects.all()
        return render(request , 'publisher_list.html' , locals())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    4、添加出版社信息操作

    实现添加数据的模板页面

    {% block main%}
        <form method="post">
            {% csrf_token %}
            <p>出版社名称<input type="text" name="name">p>
            <p>出版社类型<input type="text" name="publisher_type">p>
            <p>出版社成立时间<input type="date" name="create_time">p>
            <p>出版社地址<input type="text" name="address">p>
            <p><button type="submit" class="btn">提交button>p>
        form>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    # 添加出版社数据
    path('add_publisher/' , views.AddPublisher.as_view()),
    
    # 视图
    class AddPublisher(View):
        '''
        添加出版社数据视图
        '''
        def get(self , request):
            return render(request , 'add_publisher.html')
    
        def post(self , request):
            name = request.POST.get('name')
            publisher_type = request.POST.get('publisher_type')
            create_time = request.POST.get('create_time')
            address = request.POST.get('address')
    
            # 将数据保存到数据库中
            PublishingHouse.objects.create(
                name=name,
                publisher_type=publisher_type,
                create_time=create_time,
                address=address
            )
            # 数据保存成功 , 重定向到列表页
            return redirect('/publisher_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    5、修改出版社信息

    获取要修改的出版社信息 , 要知道是哪个出版社信息需要修改

    获取要修改的出版社信息 , 响应到页面中。

    重新接收用户修改好的出版社数据保存到数据库中。

    实现修改数据模板页

    {% block main %}
        <form method="post">
            {% csrf_token %}
            <p>出版社名称<input type="text" name="name" value="{{ edit.name }}">p>
            <p>出版社类型<input type="text" name="publisher_type" value="{{ edit.publisher_type }}">p>
            <p>出版社成立时间<input type="date" name="create_time" value="{{ edit.create_time }}">p>
            <p>出版社地址<input type="text" name="address" value="{{ edit.address }}">p>
            <p><button type="submit" class="btn">提交button>p>
        form>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    # 路由
    # 修改出版社信息
    path('edit_publisher/' , views.EditPublisher.as_view()),
    
    # 视图
    class EditPublisher(View):
        '''
        修改出版社信息的视图
        '''
        def get(self , request):
            # 获取用户要修改的出版社信息
            id = request.GET.get('id')
            edit = PublishingHouse.objects.get(id=id)
            return render(request , 'edit_publisher.html' , locals())
    
        def post(self , request):
            id = request.GET.get('id')
            name = request.POST.get('name')
            publisher_type = request.POST.get('publisher_type')
            create_time = request.POST.get('create_time')
            address = request.POST.get('address')
            edit_data = PublishingHouse.objects.filter(id=id)
            edit_data.update(
                name=name,
                publisher_type=publisher_type,
                create_time=create_time,
                address=address
            )
            return redirect('/publisher_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    6、删除出版社信息

    # 路由
    # 删除出版社信息
    path('del_publisher/' , views.del_publisher),
    
    # 视图
    def del_publisher(request):
        # 获取要删除的出版社信息:id
        id = request.GET.get('id')
        PublishingHouse.objects.filter(id=id).delete()
        return redirect('/publisher_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    五、图书信息

    1、图书模型类

    class Book(models.Model):
        '''
        图书信息模型类
        '''
        name = models.CharField(max_length=20)
        carrier = models.CharField(max_length=10)
        number_of_words = models.IntegerField()
        publisher_time = models.DateField()
        book_image = models.CharField(max_length=20)
        book_intro = models.CharField(max_length=300)
        price = models.DecimalField(max_digits=5 , decimal_places=2)
        inventory = models.IntegerField()
        publisher = models.ForeignKey(to='PublishingHouse' , on_delete=models.CASCADE)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2、图书列表页

    {% block main %}
        <table border="1" class="table table-hover table-bordered">
            <thead>
                <tr>
                    <td>序号td>
                    <td>图书名称td>
                    <td>图书价格td>
                    <td>库存td>
                    <td>查询详情td>
                    <td>操作td>
                tr>
            thead>
            <tbody>
                {% for foo in book %}
                    <tr>
                        <td>{{ foo.id }}td>
                        <td>{{ foo.name }}td>
                        <td>{{ foo.price }}td>
                        <td>{{ foo.inventory }}td>
                        <td><a href="/check_book/?id={{ foo.id }}">查看a>td>
                        <td>
                            <a href="#">修改a>
                            <a href="#">删除a>
                        td>
                    tr>
                {% endfor %}
            tbody>
        table>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    # 查看图书列表页
    path('book_list/' , views.book_list),
    
    def book_list(request):
        book = Book.objects.all()
        return render(request , 'book_list.html' , locals())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3、添加图书数据

    {% block main%}
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>图书名称<input type="text" name="name">p>
            <p>图书载体<input type="text" name="carrier">p>
            <p>图书字数<input type="text" name="number">p>
            <p>图书发表时间<input type="date" name="time">p>
            <p>图书图片<input type="file" name="book_image">p>
            <p>图书简介<textarea rows="10" cols="20" name="book_intro">textarea>p>
            <p>图书价格<input type="text" name="price">p>
            <p>图书库存<input type="text" name="inventory">p>
            <p>出版社<select multiple name="publisher_id">
                {% for foo in publisher %}
                    <option value="{{ foo.id }}">{{ foo.name }}option>
                {% endfor %}
            select>
            p>
            <p><button type="submit" class="btn">提交button>p>
        form>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    # 添加图书信息
    path('add_book/' , views.AddBook.as_view()),
    
    class AddBook(View):
        '''
        添加图书信息
        '''
        def get(self , request):
            # 获取出版社数据
            publisher = PublishingHouse.objects.all()
            return render(request , 'add_book.html' , locals())
    
        def post(self , request):
            name = request.POST.get('name')
            carrier = request.POST.get('carrier')
            number = request.POST.get('number')
            time = request.POST.get('time')
            book_image = request.FILES.get('book_image')
            book_intro = request.POST.get('book_intro')
            price = request.POST.get('price')
            inventory = request.POST.get('inventory')
            publisher_id = request.POST.get('publisher_id')
    
            # 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片
            if book_image:
                # 获取文件名
                book_image_name = book_image.name
                # 将图片保存到指定位置
                image_dir = os.path.join(STATICFILES_DIRS[0] , 'book_image' , book_image_name)
                with open(image_dir , 'wb') as f:
                    for i in book_image:
                        f.write(i)
                    else:
                        book_image = '暂无.jpg'
    
                        if not book_intro:
                            book_intro = '暂无作品介绍,正在整理中……'
    
                            Book.objects.create(
                                name=name,
                                carrier=carrier,
                                number_of_words=number,
                                publisher_time=time,
                                book_image=book_image,
                                book_intro=book_intro,
                                price=price,
                                inventory=inventory,
                                publisher_id=publisher_id
                            )
                            return redirect('/book_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    4、查看图书详情

    {% block main %}
        <h1>图书名称:{{ book.name }}h1>
        <h2>图书作者:h2>
        <table border="1" class="table table-hover table-bordered">
            <tr>
                <th>图书简介th>
                <td>{{ book.book_intro }}td>
                <th>图书图片th>
                <td><img src="/static/book_image/{{ book.book_image }}">td>
            tr>
            <tr>
                <th>文学载体th>
                <td>{{ book.carrier }}td>
                <th>图书字数th>
                <td>{{ book.number_of_words }}td>
            tr>
            <tr>
                <th>发表时间th>
                <td>{{ book.publisher_time }}td>
                <th>图书出版社th>
                <td>{{ book.publisher.name }}td>
            tr>
        table>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    # 查看图书详情
    path('check_book/' , views.book_particulars),
    
    def book_particulars(request):
        id = request.GET.get('id')
        book = Book.objects.get(id=id)
        return render(request , 'book_particulars.html' , locals())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    5、删除图书信息

    def del_book(request):
        id = request.GET.get('id')
        Book.objects.filter(id=id).delete()
        return redirect('/book_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    6、修改图书信息

    class EditBook(View):
        def get(self , request):
            id = request.GET.get('id')
            book = Book.objects.get(id=id)
            publisher = PublishingHouse.objects.all()
            return render(request , 'edit_book.html' , locals())
    
        def post(self , request):
            id = request.GET.get('id')
            name = request.POST.get('name')
            carrier = request.POST.get('carrier')
            number = request.POST.get('number')
            time = request.POST.get('time')
            book_image = request.FILES.get('book_image')
            book_intro = request.POST.get('book_intro')
            price = request.POST.get('price')
            inventory = request.POST.get('inventory')
            publisher_id = request.POST.get('publisher_id')
    
            # 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片
            if book_image:
                # 获取文件名
                book_image_name = book_image.name
                # 将图片保存到指定位置
                image_dir = os.path.join(STATICFILES_DIRS[0], 'book_image', book_image_name)
                with open(image_dir, 'wb') as f:
                    for i in book_image:
                        f.write(i)
            else:
                book_image = '暂无.jpg'
    
            if not book_intro:
                book_intro = '暂无作品介绍,正在整理中……'
            edit_data = Book.objects.filter(id=id)
            edit_data.update(
                name=name,
                carrier=carrier,
                number_of_words=number,
                publisher_time=time,
                book_image=book_image,
                book_intro=book_intro,
                price=price,
                inventory=inventory,
                publisher_id=publisher_id
            )
            return redirect('/book_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    {% block main%}
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>图书名称<input type="text" name="name" value="{{ book.name }}">p>
            <p>图书载体<input type="text" name="carrier" value="{{ book.carrier }}">p>
            <p>图书字数<input type="text" name="number" value="{{ book.number_of_words }}">p>
            <p>图书发表时间<input type="date" name="time" value="{{ book.publisher_time }}">p>
            <p>图书图片<input type="file" name="book_image">p>
            <p>图书简介<textarea rows="10" cols="20" name="book_intro">{{ book.book_intro }}textarea>p>
            <p>图书价格<input type="text" name="price" value="{{ book.price }}">p>
            <p>图书库存<input type="text" name="inventory" value="{{ book.inventory }}">p>
            <p>出版社<select multiple name="publisher_id">
                {% for foo in publisher %}
                    <option value="{{ foo.id }}">{{ foo.name }}option>
                {% endfor %}
            select>
            p>
            <p><button type="submit" class="btn">提交button>p>
        form>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    六、作者信息

    1、作者模型类

    class Author(models.Model):
        '''
        作者信息
        '''
        # 作者姓名
        name = models.CharField(max_length=15)
        # 作者照片
        author_picture_name = models.CharField(max_length=20)
        # 作者简介
        author_intro = models.CharField(max_length=150)
        # 作者图书
        book = models.ManyToManyField(to='Book')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    2、作者列表页响应

    {% block main %}
        <table border="1" class="table table-hover table-bordered">
            <thead>
                <tr>
                    <td>序号td>
                    <td>作者名称td>
                    <td>作者详情td>
                    <td>操作td>
                tr>
            thead>
            <tbody>
                {% for foo in author %}
                    <tr>
                        <td>{{ foo.id }}td>
                        <td>{{ foo.name }}td>
                        <td><a href="/check_author/?id={{ foo.id }}">查看a>td>
                        <td>
                            <a href="/edit_author/?id={{ foo.id }}">修改a>
                            <a href="/del_author/?id={{ foo.id }}">删除a>
                        td>
                    tr>
                {% endfor %}
            tbody>
        table>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    def author_list(request):
        author = Author.objects.all()
        return render(request , 'author_list.html' , locals())
    
    
    • 1
    • 2
    • 3
    • 4

    3、添加作者信息

    {% block main%}
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>作者名称<input type="text" name="name">p>
            <p>作者图片<input type="file" name="author_image">p>
            <p>作者简介<textarea rows="10" cols="20" name="author_intro">textarea>p>
            <p>作者作品
                {% for foo in book %}
                    <input type="checkbox" value="{{ foo.id }}" name="books">{{ foo.name }}
                {% endfor %}
            p>
            <p><button type="submit" class="btn">提交button>p>
        form>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    class AddAuthor(View):
        def get(self , request):
            book = Book.objects.all()
            return render(request , 'add_author.html' , locals())
    
        def post(self , request):
            name = request.POST.get('name')
            author_intro = request.POST.get('author_intro')
            author_image = request.FILES.get('author_image')
            # 前端中的多选框 , 接受的是一个列表类型的数据
            # getlist 的方式接受
            books = request.POST.getlist('books')
            # 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片
            if author_image:
                # 获取文件名
                author_image_name = author_image.name
                # 将图片保存到指定位置
                image_dir = os.path.join(STATICFILES_DIRS[0], 'author_image', author_image_name)
                with open(image_dir, 'wb') as f:
                    for i in author_image:
                        f.write(i)
            else:
                author_image = '暂无.jpg'
    
            if not author_intro:
                author_intro = '暂无作者介绍,正在整理中……'
    
            author = Author.objects.create(
                name=name,
                author_picture_name=author_image,
                author_intro=author_intro)
            author.book.set(books)
            return redirect('/author_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    4、查看作者详情数据

    def check_author(request):
        id = request.GET.get('id')
        author = Author.objects.get(id=id)
        book = Book.objects.filter(author__id=id)
        return render(request , 'check_author.html' , locals())
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    {% block main %}
        <h1>作者:{{ author.name }}h1>
        <table border="1" class="table table-hover table-bordered">
            <tr>
                <th>作者简介th>
                <td>{{ author.author_intro }}td>
                <th>作者图片th>
                <td><img src="/static/author_image/{{ author.author_picture_name }}">td>
            tr>
        table>
        <table border="1" class="table table-hover table-bordered">
            <thead>
                <tr>
                    <td>作品td>
                tr>
            thead>
            <tbody>
                <tr>
                    {% for foo in book %}
                        <td>{{ foo.name }}td>
                    {% endfor %}
    
                tr>
            tbody>
        table>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    5、修改作者信息

    {% block main%}
        <form method="post" enctype="multipart/form-data">
            {% csrf_token %}
            <p>作者名称<input type="text" name="name" value="{{ author.name }}">p>
            <p>作者图片<input type="file" name="author_image">p>
            <p>作者简介<textarea rows="10" cols="20" name="author_intro">{{ author.author_intro }}textarea>p>
            <p>作者作品
                {% for foo in book %}
                    <input type="checkbox" value="{{ foo.id }}" name="books">{{ foo.name }}
                {% endfor %}
            p>
            <p><button type="submit" class="btn">提交button>p>
        form>
    {% endblock main %}
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    class EditAuthor(View):
        def get(self , request):
            id = request.GET.get('id')
            author = Author.objects.get(id=id)
            book = Book.objects.all()
            return render(request , 'edit_author.html' , locals())
    
        def post(self , request):
            id = request.GET.get('id')
            name = request.POST.get('name')
            author_intro = request.POST.get('author_intro')
            author_image = request.FILES.get('author_image')
            # 前端中的多选框 , 接受的是一个列表类型的数据
            # getlist 的方式接受
            books = request.POST.getlist('books')
            # 在项目的静态文件夹中 , 创建一个文件夹保存图书的图片
            if author_image:
                # 获取文件名
                author_image_name = author_image.name
                # 将图片保存到指定位置
                image_dir = os.path.join(STATICFILES_DIRS[0], 'author_image', author_image_name)
                with open(image_dir, 'wb') as f:
                    for i in author_image:
                        f.write(i)
            else:
                author_image = '暂无.jpg'
    
            if not author_intro:
                author_intro = '暂无作者介绍,正在整理中……'
            edit_data = Author.objects.get(id=id)
            edit_data.name = name
            edit_data.author_intro = author_intro
            edit_data.author_picture_name = author_image
            edit_data.book.set(books)
            edit_data.save()
            return redirect('/author_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    6、删除作者

    def del_author(request):
        id = request.GET.get('id')
        Author.objects.filter(id=id).delete()
        return redirect('/author_list/')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    SpringSecurity(十五)---OAuth2的运行机制(上)-OAuth2概念和授权码模式讲解
    艾美捷细胞失巢凋亡检测试剂盒测定原理&化验方案
    Go Web开发GoFrame+Vue+ElementUI框架实战教程
    将一维数据(序列)转化为二维数据(图像)的方法汇总GAFS, MTF, Recurrence plot,STFT
    G-002 波峰焊与回流焊的区别
    JavaSE之List中ArrayList底层和LinkedList底层
    Kafka - 04 Java客户端实现消息发送和订阅
    区块链基础:编写一个最简单的合约,修改和查询
    Python 快速排序
    Cas单点登录(整合shiro版本)
  • 原文地址:https://blog.csdn.net/xiugtt6141121/article/details/138198735