• Python-S9——Day84-ORM项目实战之权限、form以及modelform


    • 01 权限菜单显示

    • 02 Django路径的自动添加问题

    • 03 原生form实现增删改查

    • 04 modelform实现增删改查

    01 权限菜单显示

    1.1 优先查找项目中的templates,如果没有,然后再去查找应用中的templates下的模板文件;

     1.1.2 如果每个应用下都有相同名称的templates或者templatetags,会根据应用的创建顺序进行查找;

     1.1.3 为避免以上情况发生,建议在templates或者templatestags目录下分别建立应用名称,然后再放置.html模板文件或者my_tag.py文件;

    整个项目的完整目录结构:

    总结一下整个项目的开发流程:

    • 使用Pycharm创建项目,进行项目的命名
    • 使用Pycharm下的Tools》Run manage.py task启动shell窗口
    • startapp app01
    • startapp rbac(Role-Based Access Control,即基于角色的访问权限控制)详情见:https://baike.baidu.com/item/RBAC/1328788?fr=aladdin
    • settings.py配置文件进行TEMPLATES以及INSTALLED_APPS的添加配置;
    • urls.py的配置;
    • app01/views.py的配置;
    • rbac/models.py的配置并进行数据库迁移操作 makemigrationsmigrate
    • rbac/admin.py的注册配置,并引入class类;
    • 进行程序的解耦合操作,进行rbac/service/permissions.py以及rbac/service/rbac.py的配置;
    • 进行自定义templatetags的自定义,my_tags.py的配置;
    • 分别添加base.html menu.html users.html roles.html 等模板文件,进行extends、include、block等方法进行关联;
    • 将基础模板文件从根目录的templates目录迁移至rbac/templates目录下

    settings.py

    """
    Django settings for s9day82_rbac project.
    
    Generated by 'django-admin startproject' using Django 1.11.1.
    
    For more information on this file, see
    https://docs.djangoproject.com/en/1.11/topics/settings/
    
    For the full list of settings and their values, see
    https://docs.djangoproject.com/en/1.11/ref/settings/
    """
    
    import os
    
    # Build paths inside the project like this: os.path.join(BASE_DIR, ...)
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    
    # Quick-start development settings - unsuitable for production
    # See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
    
    # SECURITY WARNING: keep the secret key used in production secret!
    SECRET_KEY = '0s(th#!ewf^xik5n&bqkqqjadz#q*vt+!hq(kzk5*-!t6@^0^i'
    
    # SECURITY WARNING: don't run with debug turned on in production!
    DEBUG = True
    
    ALLOWED_HOSTS = []
    
    # Application definition
    
    INSTALLED_APPS = [
        'django.contrib.admin',
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'app01.apps.App01Config',
        'rbac.apps.RbacConfig',
    ]
    
    MIDDLEWARE = [
        'django.middleware.security.SecurityMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.middleware.clickjacking.XFrameOptionsMiddleware',
        'rbac.service.rbac.ValidPermission',
    ]
    from django.middleware.security import SecurityMiddleware
    
    ROOT_URLCONF = 's9day82_rbac.urls'
    
    TEMPLATES = [
        {
            'BACKEND': 'django.template.backends.django.DjangoTemplates',
            'DIRS': [os.path.join(BASE_DIR, 'templates')]
            ,
            'APP_DIRS': True,
            'OPTIONS': {
                'context_processors': [
                    'django.template.context_processors.debug',
                    'django.template.context_processors.request',
                    'django.contrib.auth.context_processors.auth',
                    'django.contrib.messages.context_processors.messages',
                ],
            },
        },
    ]
    
    WSGI_APPLICATION = 's9day82_rbac.wsgi.application'
    
    # Database
    # https://docs.djangoproject.com/en/1.11/ref/settings/#databases
    
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        }
    }
    
    # Password validation
    # https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
    
    AUTH_PASSWORD_VALIDATORS = [
        {
            'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
        },
        {
            'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
        },
    ]
    
    # Internationalization
    # https://docs.djangoproject.com/en/1.11/topics/i18n/
    
    LANGUAGE_CODE = 'en-us'
    
    TIME_ZONE = 'UTC'
    
    USE_I18N = True
    
    USE_L10N = True
    
    USE_TZ = True
    
    # Static files (CSS, JavaScript, Images)
    # https://docs.djangoproject.com/en/1.11/howto/static-files/
    
    STATIC_URL = '/static/'

    urls.py

    """s9day82_rbac URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^users/$', views.users),
        url(r'^users/add', views.add_user),
        url(r'^users/delete/(d+)', views.del_user),
        url(r'^roles/', views.roles),
        url(r'^login/', views.login),
    ]

    views.py

    import re
    from django.shortcuts import render, HttpResponse
    
    # Create your views here.
    
    from rbac.models import *
    from rbac.service.permissions import *
    
    
    class Per(object):
        def __init__(self, actions):
            self.actions = actions
    
        def add(self):
            return "add" in self.actions
    
        def delete(self):
            return "delete" in self.actions
    
        def edit(self):
            return "edit" in self.actions
    
        def list(self):
            return "list" in self.actions
    
    
    def users(request):
        user_list = User.objects.all()
        # permission_list = request.session.get("permission_list")
        # print(permission_list)  # ['/users/', '/users/add', '/users/delete/(\d+)', '/users/edit/(\d+)']
        # 查询当前登录人的名字;
        id = request.session.get("user_id")
        user = User.objects.filter(id=id).first()
        per = Per(request.actions)
       
        return render(request, "users.html", locals())
    
    
    def add_user(request):
        return HttpResponse("Add User......")
    
    
    def del_user(request, id):
        return HttpResponse("Delete User..." + id)
    
    
    def roles(request):
        role_list = Role.objects.all()
        per = Per(request.actions)
        return render(request, "roles.html", locals())
    
    
    def login(request):
        if request.method == "POST":
            user_obj = request.POST.get("user")
            pwd = request.POST.get("pwd")
            user = User.objects.filter(name=user_obj, pwd=pwd).first()
            if user:
                # #################在session中注册用户ID###########################;
                request.session["user_id"] = user.pk
                initial_session(user, request)
                '''
                此处的values()相当于:
                temp = []#定义一个空列表;
                for role in user.roles.all();#values属性,相当于循环该对象[<Role: 保洁>, <Role: 销售>]>
                    temp.append({
                    "title":role.title,
                    "permissions__url":role.permissions.all()
                    })
                '''
                return HttpResponse("登录成功!")
        return render(request, "login.html")

    permissions.py

    def initial_session(user, request):
        # 方案1
        # #################在session注册权限列表###########################;
        # 查询当前登录用户的所有角色;
        # ret = user.roles.all()
        # print("ret", ret)  # <QuerySet [<Role: 保洁>, <Role: 销售>]>
        #
        # # 查询当前用户的所有权限;
        # permissions = user.roles.all().values(
        #     "permissions__url").distinct()  # ret_role <QuerySet [{'permissions__url': '/users/'},
        # #  {'permissions__url': '/users/add'}]>
        #
        # # 进行数据的处理,生成列表;
        # permission_list = []
        # for item in permissions:
        #     permission_list.append(item["permissions__url"])
        # print("permission_list", permission_list)  # permission_list ['/users/', '/users/add']
        #
        # request.session["permission_list"] = permission_list
    
        # 方案2;
        permissions = user.roles.all().values("permissions__url", "permissions__group_id", "permissions__action").distinct()
        print("permissions   ", permissions)  # <QuerySet [{'permissions__url': '/users/',
        # 'permissions__group_id': 1, 'permissions__action': 'list'}]>
        permission_dict = {}
        for item in permissions:
            gid = item.get('permissions__group_id')
            if not gid in permission_dict:
    
                permission_dict[gid] = {
                    "urls": [item["permissions__url"], ],
                    "actions": [item["permissions__action"], ]
                }
            else:
                permission_dict[gid]["urls"].append(item["permissions__url"])
                permission_dict[gid]["actions"].append(item["permissions__action"])
        print(permission_dict)
        request.session["permission_dict"] = permission_dict
        # 注册菜单权限;
        permissions = user.roles.all().values("permissions__url", "permissions__action",
                                              "permissions__group__title").distinct()
        print("permissions", permissions)
        menu_permission_list = []
        for item in permissions:
            if item["permissions__action"] == "list":
                menu_permission_list.append((item["permissions__url"], item["permissions__group__title"]))
        print(menu_permission_list)
        request.session["menu_permission_list"] = menu_permission_list

    admin.py

    from django.contrib import admin
    
    # Register your models here.
    
    from .models import *
    
    
    class PerConfig(admin.ModelAdmin):
        list_display = ["title", "url", "group", "action"]
    
    
    admin.site.register(User)
    admin.site.register(Role)
    admin.site.register(Permission, PerConfig)
    admin.site.register(PermissionGroup)

    rbac.py

    from django.utils.deprecation import MiddlewareMixin
    from django.shortcuts import HttpResponse, redirect
    import re
    
    
     # 自定义中间件!
    class ValidPermission(MiddlewareMixin):
        def process_request(self, request):
            # 当前访问权限;
            current_path = request.path_info
            # 1、校验权限,是否是与白名单;
            valid_url_list = ["/login/", "/reg/", "/admin/.*"]
            for valid_url in valid_url_list:
                ret = re.match(valid_url, current_path)
                if ret:
                    return None
            user_id = request.session.get("user_id")
            if not user_id:
                return redirect("/login/")
            # # 2、判断是否登录
            # permission_list = request.session.get(
            #     "permission_list",
            #     [])  # permission_list ['/users/', '/users/add', '/users/delete/(\d+)', '/users/edit/(\d+)']
            #
            # flag = False
            # for permission in permission_list:
            #     permission = "^%s$" % permission
            #     ret = re.match(permission, current_path)
            #     if ret:
            #         flag = True
            #         break
            # if not flag:
            #
            # return None
            #   3、校验是否登录;
            permission_dict = request.session.get("permission_dict")
            for item in permission_dict.values():
                urls = item['urls']
                for reg in urls:
                    reg = "^%s$" % reg
                    ret = re.match(reg, current_path)
                    if ret:
                        print("actions", item['actions'])
                        request.actions = item['actions']
                        return None
            return HttpResponse("没有访问权限!")

    models.py

    from django.db import models
    
    
    # Create your models here.
    
    class User(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        roles = models.ManyToManyField(to="Role")
    
        def __str__(self):
            return self.name
    
    
    class Role(models.Model):
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(to="Permission")
    
        def __str__(self):
            return self.title
    
    
    class Permission(models.Model):
        title = models.CharField(max_length=32)
        url = models.CharField(max_length=32)
        action = models.CharField(max_length=32, default="")
        group = models.ForeignKey("PermissionGroup", default=1)
    
        def __str__(self):
            return self.title
    
    
    class PermissionGroup(models.Model):
        title = models.CharField(max_length=32)
    
        def __str__(self):
            return self.title

    base.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
        <style>
            .header {
                width: 100%;
                height: 60px;
                background-color: #336699;
    
            }
    
            .menu {
                background-color: bisque;
                position: fixed;
                top: 60px;
                bottom: 0;
                left: 0;
                width: 200px;
            }
    
            .content {
                position: fixed;
                top: 60px;
                bottom: 0;
                right: 0;
                left: 200px;
                overflow: auto;
                padding: 30px;
            }
    
            .menu_btn {
                font-size: 18px;
                text-align: center;
                padding: 50px 0;
            }
        </style>
    </head>
    <body>
    <div class="header">
        <p>{{ user.name }}</p>
    </div>
    <div class="contain">
        {% load my_tags %}
        <div class="menu">
            {% get_menu request %}
        </div>
        <div class="content ">
            {% block con %}
    
            {% endblock %}
        </div>
    
    </div>
    </body>
    </html>

    menu.html

    <div>
        {% for item  in menu_permission_list %}
            <p class="menu_btn"><a href="{{ item.0 }}">{{ item.1 }}</a></p>
        {% endfor %} 
    </div>

    users.html

    {% extends 'base.html' %}
    {% block con %}
        <h4>用户列表</h4>
        {% if per.add  %}
            <a href="/users/add/" class="btn btn-primary">添加用户</a>
        {% endif %}
    
        <table class="table table-bordered table-striped">
            <thead>
            <tr>
                <th>序号</th>
                <th>姓名</th>
                <th>角色</th>
                <th>操作</th>
            </tr>
            </thead>
            <tbody>
    
            {% for user in user_list %}
                <tr>
                    <td>{{ forloop.counter }}</td>
                    <td>{{ user.name }}</td>
                    <td>
                        {% for role in user.roles.all %}
                            {{ role.title }}
                        {% endfor %}
                    </td>
                    <td>
                        {% if per.delete %}
                            <a href="/users/delete/{{ user.pk }}" class="btn btn-danger">删除</a>
                        {% endif %}
                        {% if per.edit %}
                            <a href="/users/edit/{{ user.pk }}" class="btn btn-info">编辑</a>
                        {% endif %}
                    </td>
                </tr>
            {% endfor %}
    
            </tbody>
        </table>
    {% endblock %}

    login.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <h4>登录页面</h4>
    
    <form action="" method="post">
        {% csrf_token %}
        用户名:<input type="text" name="user">
        密码:<input type="password" name="pwd">
        <input type="submit">
    </form>
    </body>
    </html>

    my_tags.py

    from django import template
    
    register = template.Library()
    
    
    @register.inclusion_tag("menu.html")
    def get_menu(request, ):
        # 获取当前用户可以放到菜单栏中的权限;
        menu_permission_list = request.session["menu_permission_list"]
        return {"menu_permission_list": menu_permission_list}

    02 Django路径的自动添加问题

    2.1 settings.py文件中,APPEND_SLASH默认值为True;

    2.2 在setings.py中,将APPEND_SLASH调整为False;

    #设置项是否开启URL访问地址后面不为/跳转至带有/的路径;

    03 原生form实现增删改查

    3.1 创建Django项目并制定Python解释器下安装的Django==“1.11.1” version;

    3.2 基于form实现的图书管理系统的增删改查步骤;

    • 创建django项目并指定app及Python内置解释器;
    • 检查settings.py是否配置了TEMPLATES以及INSTALLED_APPS;
    • 配置urls.py;
    • 编写视图函数views.py;
    • 编写ORM——models.py;
    • 进行admin.py的注册;
    • 通过Pycharm下的Run manage.py task进行数据库的迁移以及createsuperuser操作;
    • 编写模板——add.htmlooks.htmledit.html;

    urls.py;

    """FormsDemo URL Configuration
    
    The `urlpatterns` list routes URLs to views. For more information please see:
        https://docs.djangoproject.com/en/1.11/topics/http/urls/
    Examples:
    Function views
        1. Add an import:  from my_app import views
        2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
    Class-based views
        1. Add an import:  from other_app.views import Home
        2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
    Including another URLconf
        1. Import the include() function: from django.conf.urls import url, include
        2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
    """
    from django.conf.urls import url
    from django.contrib import admin
    from app01 import views
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        url(r'^books/', views.books),
        url(r'^book/add', views.add_book),
        url(r'^book/edit/(d+)', views.edit_book),
    ]

    views.py;

    from django.shortcuts import render, redirect
    
    # Create your views here.
    from .models import *
    
    
    def books(request):
        book_list = Book.objects.all()
        return render(request, "books.html", locals())
    
    
    def add_book(request):
        if request.method == "POST":
            title = request.POST.get("title")
            price = request.POST.get("price")
            date = request.POST.get("date")
            publish_id = request.POST.get("publish_id")
            author_pk_list = request.POST.getlist("author_pk_list")
            book_obj = Book.objects.create(title=title, price=price, date=date, publish_id=publish_id)
            book_obj.authors.add(*author_pk_list)
            return redirect('/books/')
    
        publish_list = Publish.objects.all()
        author_list = Author.objects.all()
        return render(request, "add.html", locals())
    
    
    def edit_book(request, edit_book_id):
        if request.method == "POST":
            title = request.POST.get("title")
            price = request.POST.get("price")
            date = request.POST.get("date")
            publish_id = request.POST.get("publish_id")
            author_pk_list = request.POST.getlist("author_pk_list")
    
            Book.objects.filter(pk=edit_book_id).update(title=title, price=price, date=date, publish_id=publish_id)
            book_obj = Book.objects.filter(pk=edit_book_id).first()
            book_obj.authors.set(author_pk_list)
            return redirect('/books/')
        edit_book = Book.objects.filter(pk=edit_book_id).first()
        publish_list = Publish.objects.all()
        author_list = Author.objects.all()
        return render(request, "edit.html", locals())

    models.py;

    from django.db import models
    
    
    # Create your models here.
    
    class Book(models.Model):
        title = models.CharField(max_length=32)
        price = models.DecimalField(max_digits=8, decimal_places=2)  # 999999.99
        date = models.DateField()
        publish = models.ForeignKey("Publish")
        authors = models.ManyToManyField("Author")
    
        def __str__(self):
            return self.title
    
    
    class Publish(models.Model):
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name
    
    
    class Author(models.Model):
        name = models.CharField(max_length=32)
    
        def __str__(self):
            return self.name

    admin.py;

    from django.contrib import admin
    
    # Register your models here.
    from .models import *
    
    admin.site.register(Book)
    admin.site.register(Author)
    admin.site.register(Publish)

    books.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Books</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <a href="/book/add"><button>添加书籍</button></a>
    <ul>
        <table border="1">
            {% for book in book_list %}
                <tr>
                    <td>{{ book.title }}</td>
                    <td>{{ book.price }}</td>
                    <td>{{ book.date|date:"Y-m-d" }}</td>
                    <td>{{ book.publish.name }}</td>
                    <td>{{ book.authors.all }}</td>
                    <td><a href="/book/edit/{{ book.pk }}"><button>编辑</button></a></td>
                </tr>
            {% endfor %}
    
        </table>
    </ul>
    </body>
    </html>

    add.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>add</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <h3>添加页面</h3>
    <form action="" method="post">
    {% csrf_token %}
        <p>书籍名称<input type="text" name="title"></p>
        <p>价格<input type="text" name="price"></p>
        <p>日期<input type="date" name="date"></p>
        <p>出版社
            <select name="publish_id" id="">
                {% for publish in publish_list %}
                    <option value="{{ publish.pk }}">{{ publish.name }}</option>
                {% endfor %}
            </select>
        </p>
        <p>作者
            <select name="author_pk_list" id="" multiple>
                {% for author in author_list %}
                    <option value="{{ author.pk }}">{{ author.name }}</option>
                {% endfor %}
    
            </select>
        </p>
        <input type="submit">
    </form>
    </body>
    </html>

     edit.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>add</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <h3>编辑页面</h3>
    <form action="" method="post">
        {% csrf_token %}
        <p>书籍名称<input type="text" name="title" value="{{ edit_book.title }}"></p>
        <p>价格<input type="text" name="price" value="{{ edit_book.price }}"></p>
        <p>日期<input type="date" name="date" value="{{ edit_book.date|date:"Y-m-d" }}"></p>
        <p>出版社
            <select name="publish_id" id="">
                {% for publish in publish_list %}
                    {% if edit_book.publish == publish %}
                        <option selected value="{{ publish.pk }}">{{ publish.name }}</option>
                    {% else %}
                        <option value="{{ publish.pk }}">{{ publish.name }}</option>
                    {% endif %}
                {% endfor %}
            </select>
        </p>
        <p>作者
            <select name="author_pk_list" id="" multiple>
                {% for author in author_list %}
                    {% if author in edit_book.authors.all %}
                        <option selected value="{{ author.pk }}">{{ author.name }}</option>
                    {% else %}
                        <option value="{{ author.pk }}">{{ author.name }}</option>
                    {% endif %}
    
                {% endfor %}
    
            </select>
        </p>
        <input type="submit">
    </form>
    </body>
    </html>

    04 modelform实现增删改查

    4.1 使用forms组件代替form表单;

    class BookForm(forms.Form):
        title = forms.CharField(max_length=32, label="书籍名称")
        price = forms.DecimalField(max_digits=8, decimal_places=2, label="价格")  # 999999.99
        date = forms.DateField(label="日期",
                               widget=widgets.TextInput(attrs={"type": "date"})
                               )
        # gender = forms.ChoiceField(choices=((1, "男"), (2, "女"), (3, "其他"),))
        # publish = forms.ChoiceField(choices=Publish.objects.all().values_list("pk", "name"))
        publish = forms.ModelChoiceField(queryset=Publish.objects.all())
        authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())

    4.2 基于ModelForm进行精简开发;

    views.py

    from django.shortcuts import render, redirect
    
    # Create your views here.
    from .models import *
    from django import forms
    from django.forms import widgets
    from django.forms import ModelForm
    from django.forms import widgets as wid
    
    '''
    class BookForm(forms.Form):
        title = forms.CharField(max_length=32, label="书籍名称")
        price = forms.DecimalField(max_digits=8, decimal_places=2, label="价格")  # 999999.99
        date = forms.DateField(label="日期",
                               widget=widgets.TextInput(attrs={"type": "date"})
                               )
        # gender = forms.ChoiceField(choices=((1, "男"), (2, "女"), (3, "其他"),))
        # publish = forms.ChoiceField(choices=Publish.objects.all().values_list("pk", "name"))
        publish = forms.ModelChoiceField(queryset=Publish.objects.all())
        authors = forms.ModelMultipleChoiceField(queryset=Author.objects.all())
    '''
    
    
    class BookForm(ModelForm):
        class Meta:
            model = Book
            fields = "__all__"
            # fields = ["title", "price"]
            labels = {
                "title": "书籍名称",
                "price": "价格",
                "date": "书籍日期",
                "publish": "出版社",
                "authors": "作者",
            }
            widgets = {
                "title": wid.TextInput(attrs={"class": "form-control"}),
                "price": wid.TextInput(attrs={"class": "form-control"}),
                "date": wid.TextInput(attrs={"class": "form-control"}),
                "publish": wid.TextInput(attrs={"class": "form-control"}),
                "authors": wid.TextInput(attrs={"class": "form-control"}),
            }
    
    
    def books(request):
        book_list = Book.objects.all()
        return render(request, "books.html", locals())
    
    
    def add_book(request):
        if request.method == "POST":
            form = BookForm(request.POST)
            if form.is_valid():
                form.save()
                return redirect("/books/")
        form = BookForm()
        return render(request, "add.html", locals())
    
    
    def edit_book(request, edit_book_id):
        edit_book = Book.objects.filter(pk=edit_book_id).first()
        if request.method == "POST":
            form = BookForm(request.POST, instance=edit_book)
            form.save()
            return redirect("/books/")
        form = BookForm(instance=edit_book)
        return render(request, "edit.html", locals())

    add.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>add</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
    <h3>添加页面</h3>
    <div class="col-md-4 col-md-offset-3">
        {% include 'form.html' %}
    </div>
    
    </body>
    </html>

    books.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Books</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <a href="/book/add"><button>添加书籍</button></a>
    <ul>
        <table border="1">
            {% for book in book_list %}
                <tr>
                    <td>{{ book.title }}</td>
                    <td>{{ book.price }}</td>
                    <td>{{ book.date|date:"Y-m-d" }}</td>
                    <td>{{ book.publish.name }}</td>
                    <td>{{ book.authors.all }}</td>
                    <td><a href="/book/edit/{{ book.pk }}"><button>编辑</button></a></td>
                </tr>
            {% endfor %}
    
        </table>
    </ul>
    </body>
    </html>

    edit.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>add</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    <h3>编辑页面</h3>
    {% include 'form.html' %}
    </body>
    </html>

    form.html

    <form action="" method="post" novalidate>
        {% csrf_token %}
        {% for field in form %}
            <div>
                {{ field.label }}
                {{ field }}
            </div>
        {% endfor %}
    
        <input type="submit">
    </form>
  • 相关阅读:
    LightOJ 1300 边双联通分量+交错路染色
    HDU 6143 快速幂,组合数
    windows 下fc工具
    HDU 6136 模拟
    HDU 6129 暴力,规律
    UVA Live 7770 模拟
    1096: [ZJOI2007]仓库建设
    1191: [HNOI2006]超级英雄Hero
    3224: Tyvj 1728 普通平衡树
    1208: [HNOI2004]宠物收养所
  • 原文地址:https://www.cnblogs.com/tqtl911/p/9596198.html
Copyright © 2020-2023  润新知