zoukankan      html  css  js  c++  java
  • 开发一个简易的图书增删改查页面

    需求

    """
    1. 实现用户登录、注册
    2. 列出图书列表、出版社列表、作者列表
    3. 点击作者,会在新的页面列出该作者出版的图书列表
    4. 点击出版社,会列出该出版社旗下图书列表
    5. 可以创建、修改、删除  图书、作者、出版社
    
    A. 点击修改书籍按钮,弹出模态框,模态框中展示该书的信息且信息可以修改,
    B. 书名不可重复,不可修改
    C. 修改图书信息时,使用ajax请求发送信息
    """

    页面展示

     

     

     项目目录结构(前端用到了jQuery/bootstrap/sweetalert)

     

     app01文件夹

    models.py

    from django.db import models
    
    # Create your models here.
    
    
    """
    Book              与Publish多对一;与Author多对多
    Author
    Publish
    Book2Author
    """
    
    
    class Publish(models.Model):
        """出版社名称和出版社邮箱两个字段是联合索引"""
        pid = models.AutoField(
            primary_key=True,
            verbose_name="主键",
        )
        pub_name = models.CharField(
            max_length=32,
            verbose_name="出版社名称",
        )
        pub_addr = models.CharField(
            max_length=64,
            verbose_name="出版社地址",
        )
        pub_email = models.EmailField(
            verbose_name="出版社邮箱",
        )
    
        class Meda:
            unique_together = (("pub_name", "pub_email"),)
            ordering = ['-id']
    
    
    class Author(models.Model):
        """作者名字字段是唯一索引"""
        aid = models.AutoField(
            primary_key=True,
            verbose_name="主键",
        )
        author_name = models.CharField(
            max_length=32,
            unique=True,
            verbose_name="作者名字",
        )
        author_gender_choices = (
            (1, ""),
            (2, ""),
            (3, "其他"),
        )
        author_gender = models.IntegerField(
            choices=author_gender_choices,
            default=1,
            verbose_name="作者性别",
        )
    
    
    class Book(models.Model):
        """书籍名称这个字段是唯一索引"""
        bid = models.AutoField(
            primary_key=True,
            verbose_name="主键",
        )
        book_name = models.CharField(
            max_length=32,
            verbose_name="书籍名称",
            unique=True,
        )
        book_price = models.DecimalField(
            max_digits=8,
            decimal_places=2,
            verbose_name="书籍价格",
        )
        book_date = models.DateField(
            verbose_name="书籍出版日期",
        )
        publish = models.ForeignKey(to="Publish", on_delete=models.CASCADE)
        authors = models.ManyToManyField(to="Author")

    myforms.py

    from django import forms
    from app01.models import *
    
    
    class Mylogin(forms.Form):
        """登录校验"""
        username = forms.CharField(
            label="账号",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "账号不能为空",
                "min_length": "账号不能小于3位",
                "max_length": "账号不能大于9位",
            },
            widget=forms.widgets.TextInput(attrs={"class": "form-control"}),
        )
        password = forms.CharField(
            label="密码",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "密码不能为空",
                "min_length": "密码不能小于3位",
                "max_length": "密码不能大于9位",
            },
            widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}),
        )
    
    
    class Myreg(forms.Form):
        """注册校验"""
        username = forms.CharField(
            label="账号",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "账号不能为空",
                "min_length": "账号不能小于3位",
                "max_length": "账号不能大于9位",
            },
            widget=forms.widgets.TextInput(attrs={"class": "form-control"}),
        )
        password = forms.CharField(
            label="密码",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "密码不能为空",
                "min_length": "密码不能小于3位",
                "max_length": "密码不能大于9位",
            },
            widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}),
        )
        confirm_password = forms.CharField(
            label="确认密码",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "确认密码不能为空",
                "min_length": "密码不能小于3位",
                "max_length": "密码不能大于9位",
            },
            widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}),
        )
        user_email = forms.EmailField(
            label="邮箱",
            error_messages={
                "invalid": "邮箱格式不正确",
                "required": "邮箱不能为空",
            },
            widget=forms.widgets.EmailInput(attrs={"class": "form-control"}),
        )
    
        def clean_user(self):
            """校验用户名是否包含特定字符"""
            username = self.cleaned_data.get("username")
            if "666" in username:
                self.add_error("username", "要自己666才行呀!!!")
            return username
    
        def clean(self):
            """校验密码和确认密码是否一致"""
            password = self.cleaned_data.get("password")
            confirm_password = self.cleaned_data.get("confirm_password")
            if not password == confirm_password:
                self.add_error("confirm_password", "两次密码不一致!!!")
            return self.cleaned_data
    
    
    class AddBook(forms.Form):
        """添加书籍校验"""
        book_name = forms.CharField(
            max_length=16,
            error_messages={
                "required": "书名不能为空",
                "max_length": "书名不能大于16位",
            },
        )
        book_price = forms.FloatField(
            min_value=0.01,
            max_value=999999.99,
            error_messages={
                "min_value": "最小价格不能小于0.01",
                "max_value": "最大价格不能大于999999.99",
                "required": "价格不能为空",
            },
        )
    
        def clean_book_name(self):
            """校验书名是否重复"""
            book_name = self.cleaned_data.get("book_name")
            book_obj = Book.objects.filter(
                book_name=book_name
            ).first()
            if book_obj:
                self.add_error("book_name", "书籍已存在,请重新输入...")
            return book_name
    
    
    class SetPassword(forms.Form):
        old_password = forms.CharField(
            label="原密码",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "原密码不能为空",
                "min_length": "密码不能小于3位",
                "max_length": "密码不能大于9位",
            },
            widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}),
        )
        new_password = forms.CharField(
            label="新密码",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "新密码不能为空",
                "min_length": "新密码不能小于3位",
                "max_length": "新密码不能大于9位",
            },
            widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}),
        )
        confirm_password = forms.CharField(
            label="确认密码",
            min_length=3,
            max_length=9,
            error_messages={
                "required": "确认密码不能为空",
                "min_length": "确认密码不能小于3位",
                "max_length": "确认密码不能大于9位",
            },
            widget=forms.widgets.PasswordInput(attrs={"class": "form-control"}),
        )
    
        def clean(self):
            new_password = self.cleaned_data.get("new_password")
            confirm_password = self.cleaned_data.get("confirm_password")
            if not new_password == confirm_password:
                self.add_error("confirm_password", "两次密码不一致,请重新输入...")
            return self.cleaned_data

    test.py

    from django.test import TestCase
    
    # Create your tests here.
    
    import os
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "six_module_one_work.settings")
        import django
        django.setup()
        from app01.models import *
        # 创建初始系统账户admin
        # from django.contrib.auth.models import User
        # user = User.objects.create_superuser(username='admin', password='asd123123', email='123@qq.com')
    
        # 创建初始作者表
        # author_list = []
        # for i in range(1, 6):
        #     author_obj = Author(
        #         author_name='jack%s' % i,
        #         author_gender=1,
        #     )
        #     author_list.append(author_obj)
        # Author.objects.bulk_create(author_list)
    
        # 创建初始出版社表
        # publish_list = []
        # for i in range(1, 6):
        #     publish_obj = Publish(
        #         pub_name="北京出版社%s" % i,
        #         pub_addr="北京市%s街道%s巷" % (i, i),
        #         pub_email="%s%s%s@163.com" % (i, i, i),
        #     )
        #     publish_list.append(publish_obj)
        # Publish.objects.bulk_create(publish_list)
    
        # 创建初始书籍表
        # book_list = []
        # for i in range(1, 251):
        #     book_obj = Book(
        #         book_name="python%s" % i,
        #         book_price=i,
        #         book_date="2021-02-02",
        #         publish_id=1,
        #     )
        #     book_list.append(book_obj)
        # Book.objects.bulk_create(book_list)
    
        # 创建作者书籍关系表
        # for i in range(1, 126):
        #     book_obj = Book.objects.filter(bid=i).first()
        #     book_obj.authors.add(1, 3, 5)
        # for i in range(126, 251):
        #     book_obj = Book.objects.filter(bid=i).first()
        #     book_obj.authors.add(2, 4)

    views.py

    from django.shortcuts import render, HttpResponse, redirect, reverse
    from django.contrib import auth
    from app01.myforms import *
    from django.contrib.auth.decorators import login_required
    from django.contrib.auth.models import User
    from app01.models import *
    from django.core.paginator import Paginator, EmptyPage
    # Create your views here.
    
    FLAG = False
    
    
    def register(request):
        form_obj = Myreg()
        if request.method == "POST":
            form_obj = Myreg(request.POST)
            if form_obj.is_valid():
                if not User.objects.filter(username=request.POST.get("username")).first():
                    User.objects.create_user(
                        username=request.POST.get("username"),
                        email=request.POST.get("user_email"),
                        password=request.POST.get("password"),
                    )
                    global FLAG
                    FLAG = True
                    return redirect("/login/")
                else:
                    title = "swal('注册用户已存在...')"
        return render(request, "reg.html", locals())
    
    
    def login(request):
        form_obj = Mylogin()
        global FLAG
        if FLAG:
            title = "swal('注册成功...')"
        else:
            title = ""
        target_url = request.GET.get("next", "/index/")
        if request.method == "POST":
            form_obj = Mylogin(request.POST)
            if form_obj.is_valid():
                username = request.POST.get("username")
                password = request.POST.get("password")
                user = auth.authenticate(
                    request,
                    username=username,
                    password=password,
                )
                if user is not None:
                    auth.login(request, user)
                    return redirect(target_url)
        FLAG = False
        return render(request, "login.html", locals())
    
    
    @login_required
    def index(request):
        authors = Author.objects.all().order_by("aid")
        publishs = Publish.objects.all().order_by("pid")
        book_obj = Book.objects.all().order_by("bid")
        paginator_obj = Paginator(book_obj, 10)
        page_num = int(request.GET.get("page", 1))
        try:
            current_page = paginator_obj.page(page_num)
        except EmptyPage as e:
            current_page = paginator_obj.page(1)
        if paginator_obj.num_pages > 11:
            if page_num-5 < 1:
                page_range = range(1, 12)
            elif page_num+5 > paginator_obj.num_pages:
                page_range = range(paginator_obj.num_pages-10, paginator_obj.num_pages+1)
            else:
                page_range = range(page_num-5, page_num+6)
        else:
            page_range = range(1, paginator_obj.num_pages+1)
        return render(request, "index.html", locals())
    
    
    @login_required
    def add_book(request):
        authors = Author.objects.all().order_by("aid")
        publishs = Publish.objects.all().order_by("pid")
        form_obj = AddBook()
        if request.method == "POST":
            form_obj = AddBook(request.POST)
            if form_obj.is_valid():
                book_obj = Book.objects.create(
                    book_name=request.POST.get("book_name"),
                    book_price=request.POST.get("book_price"),
                    book_date=request.POST.get("book_date"),
                    publish_id=request.POST.get("publish_id"),
                )
                author_list = request.POST.getlist("author_id")
                book_obj.authors.add(*author_list)
                return redirect("/index/")
        return render(request, "add_book.html", locals())
    
    
    @login_required
    def delete_book(request, number, page):
        Book.objects.filter(bid=number).delete()
        book_obj = Book.objects.all().order_by("bid")
        paginator_obj = Paginator(book_obj, 10)
        if page not in paginator_obj.page_range:
            page -= 1
        url = "/index/?page=%s" % page
        return HttpResponse(url)
    
    
    @login_required
    def edit_book(request, number, page):
        print(request.path_info)
        book_obj = Book.objects.filter(bid=number).first()
        if request.is_ajax():
            Book.objects.filter(bid=number).update(
                book_price=request.POST.get("book_price"),
                book_date=request.POST.get("book_date"),
                publish_id=int(request.POST.get("publish_id")),
            )
            authors_id = request.POST.getlist("authors_id[]")
            book_obj.authors.set(authors_id)
            url = "/index/?page=%s" % page
            return HttpResponse(url)
    
    
    @login_required
    def show_publish(request, number):
        publish_obj = Publish.objects.filter(pid=number).first()
        books_obj = Publish.objects.filter(pid=number).values_list(
            "book__book_name",
            "book__book_price",
            "book__book_date",
        ).order_by('pid')
        paginator_obj = Paginator(books_obj, 10)
        page_num = int(request.GET.get("page", 1))
        try:
            current_page = paginator_obj.page(page_num)
        except EmptyPage as e:
            current_page = paginator_obj.page(1)
        if paginator_obj.num_pages > 11:
            if page_num-5 < 1:
                page_range = range(1, 12)
            elif page_num+5 > paginator_obj.num_pages:
                page_range = range(paginator_obj.num_pages-10, paginator_obj.num_pages+1)
            else:
                page_range = range(page_num-5, page_num+6)
        else:
            page_range = range(1, paginator_obj.num_pages+1)
        if request.method == "POST":
            Publish.objects.filter(pid=number).update(
                pub_name=request.POST.get("pub_name"),
                pub_addr=request.POST.get("pub_addr"),
                pub_email=request.POST.get("pub_email"),
            )
            url = reverse("app01_show_publish", args=(number,))
            return redirect(url)
        return render(request, "show_publish.html", locals())
    
    
    @login_required
    def add_publish(request):
        if request.method == "POST":
            if request.POST.get("pub_name") and request.POST.get("pub_addr") and request.POST.get("pub_email"):
                publish_obj = Publish.objects.create(
                    pub_name=request.POST.get("pub_name"),
                    pub_addr=request.POST.get("pub_addr"),
                    pub_email=request.POST.get("pub_email"),
                )
                if publish_obj:
                    return redirect("/index/")
        return render(request, "add_publish.html", locals())
    
    
    @login_required
    def del_publish(request, name):
        Publish.objects.filter(pub_name=name).delete()
        return redirect("/index/")
    
    
    @login_required
    def show_author(request, number):
        author_obj = Author.objects.filter(aid=number).first()
        book_obj = Author.objects.filter(aid=number).values_list(
            "book__book_name",
            "book__book_price",
            "book__book_date",
        ).order_by('aid')
        paginator_obj = Paginator(book_obj, 10)
        page_num = int(request.GET.get("page", 1))
        try:
            current_page = paginator_obj.page(page_num)
        except EmptyPage as e:
            current_page = paginator_obj.page(1)
        if paginator_obj.num_pages > 11:
            if page_num-5 < 1:
                page_range = range(1, 12)
            elif page_num+5 > paginator_obj.num_pages:
                page_range = range(paginator_obj.num_pages-10, paginator_obj.num_pages+1)
            else:
                page_range = range(page_num-5, page_num+6)
        else:
            page_range = range(1, paginator_obj.num_pages+1)
        if request.method == "POST":
            Author.objects.filter(aid=number).update(
                author_name=request.POST.get("author_name"),
            )
            url = reverse("app01_show_author", args=(number,))
            return redirect(url)
        return render(request, "show_author.html", locals())
    
    
    @login_required
    def add_author(request):
        if request.method == "POST":
            if request.POST.get("author_name"):
                try:
                    author_obj = Author.objects.create(
                        author_name=request.POST.get("author_name"),
                    )
                    if author_obj:
                        return redirect("/index/")
                except Exception as e:
                    title = "swal('该作者已存在...')"
        return render(request, "add_author.html", locals())
    
    
    @login_required
    def del_author(request, name):
        Author.objects.filter(author_name=name).delete()
        return redirect("/index/")
    
    
    @login_required
    def logout(request):
        auth.logout(request)
        return redirect("/login/")
    
    
    @login_required
    def set_password(request):
        form_obj = SetPassword()
        user = request.user
        if request.method == "POST":
            form_obj = SetPassword(request.POST)
            if form_obj.is_valid():
                old_password = request.POST.get("old_password")
                new_password = request.POST.get("new_password")
                confirm_password = request.POST.get("confirm_password")
                if user.check_password(old_password):
                    user.set_password(new_password)
                    user.save()
                    return redirect("/login/")
                else:
                    title = "swal('原密码输入错误...')"
        return render(request, "set_password.html", locals())

    six_module_one_work文件夹

     __init__.py

    import pymysql
    
    pymysql.install_as_MySQLdb()

    settings.py

    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': '2021122101',
            'HOST': '127.0.0.1',
            'PORT': 3306,
            'USER': 'root',
            'PASSWORD': '123456',
        }
    }
    
    STATICFILES_DIRS = [
        os.path.join(BASE_DIR, "static"),
    ]
    
    LOGIN_URL = "/login/"

    urls.py

    from django.contrib import admin
    from django.urls import path
    from app01 import views
    
    urlpatterns = [
        path('admin/', admin.site.urls),
        path("login/", views.login, name="app01_login"),
        path("reg/", views.register, name="app01_reg"),
        path("index/", views.index, name="app01_index"),
        path("add_book/", views.add_book, name="app01_add_book"),
        path("delete_book/<int:number>/<int:page>/", views.delete_book, name="app01_delete_book"),
        path("edit_book/<int:number>/<int:page>/", views.edit_book, name="app01_edit_book"),
        path("show_publish/<int:number>/", views.show_publish, name="app01_show_publish"),
        path("add_publish/", views.add_publish, name="app01_add_publish"),
        path("del_publish/<str:name>/", views.del_publish, name="app01_del_publish"),
        path("show_author/<int:number>/", views.show_author, name="app01_show_author"),
        path("add_author/", views.add_author, name="app01_add_author"),
        path("del_author/<str:name>/", views.del_author, name="app01_del_author"),
        path("logout/", views.logout, name="app01_logout"),
        path("set_password/", views.set_password, name="app01_set_password"),
        path("", views.login),
    ]

    templates文件夹

    add_author.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
        <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
        <script src="{% static 'sweetalert/sweetalert.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3>添加作者</h3>
                <a href="{% url 'app01_index' %}" class="pull-right"><button class="btn btn-primary">首页</button></a>
                <br><br>
                <form action="" method="post">
                    {% csrf_token %}
                    <p>
                        作者姓名:
                        <input type="text" name="author_name" class="form-control">
                    </p>
                    <p>
                        <input type="submit" class="btn btn-block btn-info">
                    </p>
                </form>
            </div>
        </div>
    </div>
    <script>
        {{ title|safe }}
    </script>
    </body>
    </html>

    add_book.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3 class="text-center">添加书籍</h3>
                <a href="{% url 'app01_index' %}" class="pull-right"><button class="btn btn-primary">首页</button></a>
                <br><br>
                <form action="" method="post" novalidate>
                    {% csrf_token %}
                    <p>
                        书籍名称:
                        <input type="text" name="book_name" class="form-control">
                        <span style="color: red">{{ form_obj.book_name.errors.0 }}</span>
                    </p>
                    <p>
                        书籍价格:
                        <input type="text" name="book_price" class="form-control">
                        <span style="color: red">{{ form_obj.book_price.errors.0 }}</span>
                    </p>
                    <p>
                        出版日期:
                        <input type="date" name="book_date" class="form-control">
                    </p>
                    <p>
                        出版社:
                        <select name="publish_id" id="" class="form-control">
                            {% for publish in publishs %}
                                <option value="{{ publish.pk }}">{{ publish.pub_name }}</option>
                            {% endfor %}
                        </select>
                    </p>
                    <p>
                        作者:
                        <select name="author_id" id="" class="form-control" multiple>
                            {% for author in authors %}
                                <option value="{{ author.pk }}">{{ author.author_name }}</option>
                            {% endfor %}
                        </select>
                    </p>
                    <input type="submit" value="添加" class="btn btn-success btn-block">
                </form>
            </div>
        </div>
    </div>
    </body>
    </html>

    add_publish.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3>添加出版社</h3>
                <a href="{% url 'app01_index' %}" class="pull-right"><button class="btn btn-primary">首页</button></a>
                <br><br>
                <form action="" method="post">
                    {% csrf_token %}
                    <p>
                        出版社名称:
                        <input type="text" name="pub_name" class="form-control">
                    </p>
                    <p>
                        出版社地址:
                        <input type="text" name="pub_addr" class="form-control">
                    </p>
                    <p>
                        出版社邮箱:
                        <input type="text" name="pub_email" class="form-control">
                    </p>
                    <p>
                        <input type="submit" value="添加" class="btn btn-info btn-block">
                    </p>
                </form>
            </div>
        </div>
    </div>
    </body>
    </html>

    index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
        <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
        <script src="{% static 'sweetalert/sweetalert.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <nav class="navbar navbar-inverse">
                <div class="container-fluid">
                    <!-- Brand and toggle get grouped for better mobile display -->
                    <div class="navbar-header">
                        <button type="button" class="navbar-toggle collapsed" data-toggle="collapse"
                                data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
                            <span class="sr-only">Toggle navigation</span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </button>
                        <a class="navbar-brand" href="#">Brand</a>
                    </div>
    
                    <!-- Collect the nav links, forms, and other content for toggling -->
                    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                        <ul class="nav navbar-nav">
                            <li class="active"><a href="#">Link <span class="sr-only">(current)</span></a></li>
                            <li><a href="#">Link</a></li>
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
                                   aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                                <ul class="dropdown-menu">
                                    <li><a href="#">Action</a></li>
                                    <li><a href="#">Another action</a></li>
                                    <li><a href="#">Something else here</a></li>
                                    <li role="separator" class="divider"></li>
                                    <li><a href="#">Separated link</a></li>
                                    <li role="separator" class="divider"></li>
                                    <li><a href="#">One more separated link</a></li>
                                </ul>
                            </li>
                        </ul>
                        <form class="navbar-form navbar-left">
                            <div class="form-group">
                                <input type="text" class="form-control" placeholder="Search">
                            </div>
                            <button type="submit" class="btn btn-default">Submit</button>
                        </form>
                        <ul class="nav navbar-nav navbar-right">
                            <li><a href="#">Link</a></li>
                            <li class="dropdown">
                                <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button"
                                   aria-haspopup="true" aria-expanded="false">Dropdown <span class="caret"></span></a>
                                <ul class="dropdown-menu">
                                    <li><a href="#">Action</a></li>
                                    <li><a href="#">Another action</a></li>
                                    <li><a href="#">Something else here</a></li>
                                    <li role="separator" class="divider"></li>
                                    <li><a href="#">Separated link</a></li>
                                </ul>
                            </li>
                        </ul>
                    </div><!-- /.navbar-collapse -->
                </div><!-- /.container-fluid -->
            </nav>
            <div class="row">
                    <a href="{% url 'app01_logout' %}">
                        <button class="btn btn-danger pull-left">退出</button>
                    </a>
                    &nbsp;
                    <a href="{% url 'app01_set_password' %}">
                        <button class="btn btn-success">修改密码</button>
                    </a>
                    <a href="{% url 'app01_add_book' %}">
                        <button class="btn btn-primary pull-right">添加书籍</button>
                    </a>
                    <br><br><br>
                    <table class="table table-bordered table-striped table-condensed">
                        <thead>
                        <tr>
                            <th class="text-center">序号</th>
                            <th class="text-center">书籍名称</th>
                            <th class="text-center">书籍价格</th>
                            <th class="text-center">出版日期</th>
                            <th class="text-center">出版社</th>
                            <th class="text-center">作者</th>
                            <th class="text-center">操作</th>
                        </tr>
                        </thead>
                        <tbody>
                        {% for book in current_page %}
                            <tr class="text-center">
                                <td>
                                    {% if forloop.first %}
                                        {{ current_page.start_index }}
                                    {% else %}
                                        {{ current_page.start_index|add:forloop.counter0 }}
                                    {% endif %}
                                </td>
                                <td>{{ book.book_name }}</td>
                                <td>{{ book.book_price }}</td>
                                <td>{{ book.book_date|date:'Y-m-d' }}</td>
                                <td><a href="{% url 'app01_show_publish' book.publish.pid %}">{{ book.publish.pub_name }}</a></td>
                                <td>
                                    {% for author in book.authors.all %}
                                        {% if forloop.last %}
                                            <a href="{% url 'app01_show_author' author.aid %}" target="_blank">{{ author.author_name }}</a>
                                        {% else %}
                                            <a href="{% url 'app01_show_author' author.aid %}" target="_blank">{{ author.author_name }},</a>
                                        {% endif %}
                                    {% endfor %}
                                </td>
                                <td>
                                    <button class="btn btn-danger btn-xs b2" number_01="{{ book.pk }}" >编辑</button>
                                    <button class="btn btn-warning btn-xs b1" number={{ book.pk }}>删除</button>
                                </td>
                            </tr>
                        {% endfor %}
                        <select name="" id="i6" style="display: none">
                            {% for publish in publishs %}
                                <option value={{ publish.pid }}>{{ publish.pub_name }}</option>
                            {% endfor %}
                        </select>
                        <select name="" id="i7" style="display: none" multiple>
                            {% for author in authors %}
                                <option value={{ author.pk }}>{{ author.author_name }}</option>
                            {% endfor %}
                        </select>
                        </tbody>
                    </table>
                    <nav aria-label="Page navigation" class="text-center">
                        <ul class="pagination">
                            <li>
                                <a href="?page=1" aria-label="Previous">
                                    <span aria-hidden="true">首页</span>
                                </a>
                            </li>
                            {% if current_page.has_previous %}
                                <li>
                                    <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
                                        <span aria-hidden="true">&laquo;</span>
                                    </a>
                                </li>
                            {% else %}
                                <li class="disabled">
                                    <span aria-hidden="true">&laquo;</span>
                                </li>
                            {% endif %}
                            {% for page in page_range %}
                                {% if page == page_num %}
                                    <li class="active"><a href="?page={{ page }}">{{ page }}</a></li>
                                {% else %}
                                    <li><a href="?page={{ page }}">{{ page }}</a></li>
                                {% endif %}
                            {% endfor %}
                            {% if current_page.has_next %}
                                <li>
                                    <a href="?page={{ current_page.next_page_number }}" aria-label="Next">
                                        <span aria-hidden="true">&raquo;</span>
                                    </a>
                                </li>
                            {% else %}
                                <li class="disabled">
                                    <span aria-hidden="true">&raquo;</span>
                                </li>
                            {% endif %}
                            <li>
                                <a href="?page={{ paginator_obj.num_pages }}" aria-label="Previous">
                                    <span aria-hidden="true">尾页</span>
                                </a>
                            </li>
                        </ul>
                    </nav>
    
                    <!-- Modal -->
                    <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
                        <div class="modal-dialog" role="document">
                            <div class="modal-content">
                                <div class="modal-header">
                                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span
                                            aria-hidden="true">&times;</span></button>
                                    <h4 class="modal-title" id="myModalLabel">编辑书籍</h4>
                                </div>
                                <div class="modal-body">
                                    <p>
                                        书籍名称:
                                        <input type="text" name="book_name" class="form-control" id="i1" disabled>
                                    </p>
                                    <p>
                                        书籍价格:
                                        <input type="text" name="book_price" class="form-control" id="i2">
                                    </p>
                                    <p>
                                        出版日期:
                                        <input type="date" name="book_date" class="form-control" id="i3">
                                    </p>
                                    <p>
                                        出版社:
                                        <select name="publish_id" id="i4" class="form-control">
                                        </select>
                                    </p>
                                    <p>
                                        作者:
                                        <select name="authors_id" id="i5" class="form-control" multiple>
                                        </select>
                                    </p>
                                </div>
                                <div class="modal-footer">
                                    <button type="button" class="btn btn-default" data-dismiss="modal">取消</button>
                                    <button type="button" class="btn btn-primary b3">保存</button>
                                </div>
                            </div>
                        </div>
                    </div>
            </div>
        </div>
    </div>
    
    <script>
        $(".b1").click(function () {
            let number = $(this).attr("number");
            swal({
                    title: "确定要删除吗?",
                    text: "删除后书籍就没有了!",
                    type: "warning",
                    showCancelButton: true,
                    confirmButtonClass: "btn-danger",
                    confirmButtonText: "确定!",
                    cancelButtonText: "取消!",
                    closeOnConfirm: false,
                    closeOnCancel: false
                },
                function (isConfirm) {
                    if (isConfirm) {
                        $.ajax({
                            url: '/delete_book/' + number + '/{{ page_num }}/',
                            type: "post",
                            data: {'csrfmiddlewaretoken': '{{ csrf_token }}'},
                            success: function (data) {
                                setTimeout(function () {
                                    location.href = data;
                                }, 3000);
                            }
                        });
                        swal("Deleted!", "您已成功删除该书籍", "success");
                    } else {
                        swal("Cancelled", "您已取消删除该书籍", "error");
                    }
                })
        })
        $(".b2").click(function () {
            $('#myModal').modal('show');
    
            let value1 = $(this).parentsUntil("tbody").children('td').eq(1).html();
            let value2 = $(this).parentsUntil("tbody").children('td').eq(2).html();
            let value3 = $(this).parentsUntil("tbody").children('td').eq(3).html();
            let value_10 = $(this).parentsUntil("tbody").children("td").eq(4).children('a').html();
            let value_11 = $(this).parentsUntil("tbody").children("td").eq(5).children("a");
    
            $("#i1").val(value1);
            $("#i2").val(value2);
            $("#i3").val(value3);
    
            let value4 = $("#i6").children();
            $(value4).each(function () {
                $("#i4").append($(this));
            })
            $("#i4").children().each(function () {
                if ($(this).html() === value_10) {
                    $(this).prop("selected", true);
                }
            })
    
            let value5 = $("#i7").children();
            $(value5).each(function () {
                $("#i5").append($(this));
            })
            let array = new Array();
            $(value_11).each(function () {
                let ss = $(this).html().split(',')[0];
                array.push(ss);
            })
            $.each(array, function (index, value) {
                $("#i5").children("option").each(function () {
                    if ($(this).html() === value) {
                        $(this).prop("selected", true);
                    }
                })
            })
    
            let number = $(this).attr("number_01");
            $(".b3").attr("number_02", number);
        })
        $(".b3").click(function () {
            let book_name = $("#i1").val();
            let book_price = $("#i2").val();
            let book_date = $("#i3").val();
            let publish_id = $("#i4").val();
            let authors_id = $("#i5").val();
            let number = $(this).attr("number_02");
            $.ajax({
                url: '/edit_book/' + number + '/{{ page_num }}/',
                type: "post",
                data: {
                    'csrfmiddlewaretoken': '{{ csrf_token }}',
                    'book_name': book_name,
                    'book_price': book_price,
                    'book_date': book_date,
                    'publish_id': publish_id,
                    'authors_id': authors_id,
                },
                success: function (data) {
                    setTimeout(function () {
                        {#location.href = data;#}
                        window.location.reload();
                    }, 2000);
                }
            })
            swal("modify successfully!", "您已成功修改该书籍", "success");
            $('#myModal').modal('hide');
        })
    </script>
    </body>
    </html>

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
        <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
        <script src="{% static 'sweetalert/sweetalert.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3 class="text-center text-danger">登录</h3>
                <form action="" method="post" novalidate>
                    {% csrf_token %}
                    {% for form in form_obj %}
                    <p>
                    {{ form.label }}: {{ form }}
                    <span style="color: red">{{ form.errors.0 }}</span>
                    </p>
                    {% endfor %}
                    <input type="submit" value="登录" class="btn btn-block btn-primary">
                </form>
                <p class="pull-right">
                    <span class="text-danger">没有账号?</span>
                    <a href="{% url 'app01_reg' %}">点击注册</a>
                </p>
            </div>
        </div>
    </div>
    <script>{{ title|safe }}</script>
    </body>
    </html>

    reg.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
        <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
        <script src="{% static 'sweetalert/sweetalert.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3 class="text-center text-warning">注册</h3>
                <form action="" method="post" novalidate>
                    {% csrf_token %}
                    {% for form in form_obj %}
                    <p>
                    {{ form.label }}: {{ form }}
                    <span style="color: red">{{ form.errors.0 }}</span>
                    </p>
                    {% endfor %}
                    <input type="submit" value="注册" class="btn btn-primary btn-block">
                </form>
                <p class="pull-right">
                    <span class="text-danger">已有账号?</span>
                    <a href="{% url 'app01_login' %}">点击登录</a>
                </p>
            </div>
        </div>
    </div>
    <script>{{ title|safe }}</script>
    </body>
    </html>

    set_password.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
        <link rel="stylesheet" href="{% static 'sweetalert/sweetalert.css' %}">
        <script src="{% static 'sweetalert/sweetalert.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3 class="text-danger text-center">修改密码</h3>
                <a href="{% url 'app01_index' %}">
                    <button class="btn btn-primary pull-right">首页</button>
                </a>
                <br><br>
                <form action="" method="post" novalidate>
                    {% csrf_token %}
                    {% for form in form_obj %}
                    <p>
                        {{ form.label }}: {{ form }}
                        <span style="color: red">{{ form.errors.0 }}</span>
                    </p>
                    {% endfor %}
                    <p>
                        <input type="submit" class="btn btn-success btn-block">
                    </p>
                </form>
            </div>
        </div>
    </div>
    <script>
        {{ title|safe }}
    </script>
    </body>
    </html>

    show_author.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                <h3 class="text-center">作者信息及所出版书籍</h3>
                <a href="{% url 'app01_index' %}" class="pull-right"><button class="btn btn-primary">首页</button></a>
                <a href="{% url 'app01_add_author' %}" class="pull-left"><button class="btn btn-danger">添加作者</button></a>
                &nbsp;
                <a href="{% url 'app01_del_author' author_obj.author_name %}"><button class="btn btn-warning">删除作者</button></a>
                <form action="" method="post">
                    {% csrf_token %}
                    <br><br>
                    <p>
                        作者姓名:
                        <input type="text" name="author_name" class="form-control" value="{{ author_obj.author_name }}">
                    </p>
                    <p>
                        <input type="submit" value="更改" class="btn btn-block btn-info">
                    </p>
                </form>
                <table class="table table-bordered table-hover table-condensed">
                    <thead>
                    <tr>
                        <th class="text-center">书籍名称</th>
                        <th class="text-center">书籍价格</th>
                        <th class="text-center">出版日期</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for book in current_page %}
                    <tr class="text-center">
                    <td>{{ book.0 }}</td>
                    <td>{{ book.1 }}</td>
                    <td>{{ book.2|date:'Y-m-d' }}</td>
                    </tr>
                    {% endfor %}
                    </tbody>
                </table>
                <nav aria-label="Page navigation" class="text-center">
                    <ul class="pagination">
                        {% if current_page.has_previous %}
                            <li>
                                <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                </a>
                            </li>
                        {% else %}
                            <li class="disabled">
                                <span aria-hidden="true">&laquo;</span>
                            </li>
                        {% endif %}
    
                        {% for page in page_range %}
                            {% if page == page_num %}
                            <li class="active"><a href="?page={{ page }}">{{ page }}</a></li>
                                {% else %}
                                <li><a href="?page={{ page }}">{{ page }}</a></li>
                            {% endif %}
                        {% endfor %}
    
                        {% if current_page.has_next %}
                            <li>
                                <a href="?page={{ current_page.next_page_number }}" aria-label="Next">
                                    <span aria-hidden="true">&raquo;</span>
                                </a>
                            </li>
                        {% else %}
                            <li class="disabled">
                                    <span aria-hidden="true">&raquo;</span>
                            </li>
                        {% endif %}
                    </ul>
                </nav>
            </div>
        </div>
    </div>
    </body>
    </html>

    show_publish.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery3.6.js' %}"></script>
        <link rel="stylesheet" href="{% static 'bootstrap-3.4.1-dist/css/bootstrap.min.css' %}">
        <script src="{% static 'bootstrap-3.4.1-dist/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <div class="row">
            <div class="col-md-6 col-md-offset-3">
                    <h3 class="text-center">出版社信息及所出版书籍</h3>
                    <a href="{% url 'app01_index' %}" class="pull-right"><button class="btn btn-primary">首页</button></a>
                    <a href="{% url 'app01_add_publish' %}" class="pull-left"><button class="btn btn-danger">添加出版社</button></a>
                    &nbsp;
                    <a href="{% url 'app01_del_publish' publish_obj.pub_name %}"><button class="btn btn-warning">删除出版社</button></a>
                <form action="" method="post">
                    {% csrf_token %}
                    <br><br>
                    <p>
                        出版社名称:
                        <input type="text" name="pub_name" value="{{ publish_obj.pub_name }}" class="form-control">
                    </p>
                    <p>
                        出版社地址:
                        <input type="text" name="pub_addr" value="{{ publish_obj.pub_addr }}" class="form-control">
                    </p>
                    <p>
                        出版社邮箱:
                        <input type="text" name="pub_email" value="{{ publish_obj.pub_email }}" class="form-control">
                    </p>
                    <p>
                        <input type="submit" value="更改" class="btn btn-block btn-info">
                    </p>
                </form>
                <table class="table table-bordered table-hover table-condensed">
                    <thead>
                    <tr>
                        <th class="text-center">书籍名称</th>
                        <th class="text-center">书籍价格</th>
                        <th class="text-center">出版日期</th>
                    </tr>
                    </thead>
                    <tbody>
                    {% for book in current_page %}
                        <tr class="text-center">
                            <td>{{ book.0 }}</td>
                            <td>{{ book.1 }}</td>
                            <td>{{ book.2|date:'Y-m-d' }}</td>
                        </tr>
                    {% endfor %}
                    </tbody>
                </table>
                <nav aria-label="Page navigation" class="text-center">
                    <ul class="pagination">
                        {% if current_page.has_previous %}
                            <li>
                                <a href="?page={{ current_page.previous_page_number }}" aria-label="Previous">
                                    <span aria-hidden="true">&laquo;</span>
                                </a>
                            </li>
                        {% else %}
                            <li class="disabled">
                                <span aria-hidden="true">&laquo;</span>
                            </li>
                        {% endif %}
    
                        {% for page in page_range %}
                            {% if page == page_num %}
                            <li class="active"><a href="?page={{ page }}">{{ page }}</a></li>
                                {% else %}
                                <li><a href="?page={{ page }}">{{ page }}</a></li>
                            {% endif %}
                        {% endfor %}
    
                        {% if current_page.has_next %}
                            <li>
                                <a href="?page={{ current_page.next_page_number }}" aria-label="Next">
                                    <span aria-hidden="true">&raquo;</span>
                                </a>
                            </li>
                        {% else %}
                            <li class="disabled">
                                    <span aria-hidden="true">&raquo;</span>
                            </li>
                        {% endif %}
                    </ul>
                </nav>
            </div>
        </div>
    </div>
    </body>
    </html>

    README.txt

    """
    环境配置:
            Django版本:2.0.1
            MySQL版本:5.7.35
            MySQL准备数据库:'2021122101'
            MySQL链接用户名及密码:'root'/'123456'
    
    系统初始化数据:
            运行app01.tests.py中注释的代码即可
            初始化数据有系统初始登录账号及密码,作者/出版社/书籍/作者书籍关系这几张表数据
    
    功能:
            项目启动后,首先进入登录页面,登录页面与注册页面各有a标签链接进行交互切换,注册成功后自动跳转到登陆页面;
            首页展示了书籍列表,可以对书籍进行添加、编辑、删除操作;出版社及作者均可进行点击查看,跳转到对应页面查看信息;
            点击出版社,页面会展示该出版社所出版的所有书籍,还可对出版社进行添加、编辑、删除操作;
            点击作者,弹出新页面,该页面展示该作者所关联的书籍信息,还可对作者进行添加、编辑、删除操作;
            首页点击退出,即退出登录回到登录页面;
    
            修改书籍信息,弹出模态框,模态框回显该书籍信息,且书籍名称不可编辑,点击模态框保存按钮发送Ajax请求;
            添加书籍信息,书籍名称不能重复;
            删除书籍,均有二次确认操作;
    """

    如何一次性将项目所依赖的三方库版本信息导入及导出?

    """
    pycharm中的命令行输入如下命令即可:
    
    生成requirements.txt文件:pip freeze > requirements.txt
    
    安装requirements.txt依赖:pip install -r requirements.txt
    """
    

    """ requirements.txt导出信息展示 certifi==2021.5.30 charset-normalizer==2.0.4 click==8.0.1 colorama==0.4.4 DBUtils==2.0.2 decorator==4.4.2 Django==2.0.1 et-xmlfile==1.1.0 Flask==2.0.1 idna==3.2 imageio==2.9.0 imageio-ffmpeg==0.4.5 itsdangerous==2.0.1 Jinja2==3.0.1 MarkupSafe==2.0.1 moviepy==1.0.3 numpy==1.21.2 openpyxl==3.0.7 Pillow==8.3.2 prettytable==2.2.0 proglog==0.1.9 PyMySQL==1.0.2 pytz==2021.3 requests==2.26.0 tqdm==4.62.2 urllib3==1.26.6 wcwidth==0.2.5 Werkzeug==2.0.1 """

    该程序已发现的小BUG

    """
    编辑书籍信息的模态框,选择作者是多选的下拉框,没有给模态框的取消按钮绑定点击事件,所以当重新选择了作者后点击取消按钮,此时再次点击书籍编辑按钮弹出模态框时,作者的默认选中标签信息与书籍的作者信息不相符。
    
    解决方案:给模态框的取消按钮及右上角关闭按钮都绑定同一个事件,即把作者的多选下拉框的子标签option标签的默认选中属性都取消?
    """
    while True: print('studying...')
  • 相关阅读:
    深入理解Elasticsearch写入过程 使用routing会导致docid不再全局唯一 Allocate策略 + routing参数
    force merge原理 + ES写入数据的过程
    Linux内核参数--time-wait回收--不建议设置
    elasticsearch迁移--利用腾讯云cos和nfs
    蓝鲸安装失败
    Apache Tomcat/8.5.51 secretRequired="true"
    自定义Nginx返回页面
    本地yum 源 iso文件 安装ansible
    elasticsearch字段属性值截断为32位
    rabbitmq-consul-apollo部署文档
  • 原文地址:https://www.cnblogs.com/xuewei95/p/15729766.html
Copyright © 2011-2022 走看看