• 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的配置并进行数据库迁移操作 makemigrations\migrate
  • 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.html\books.html\edit.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="">
{% 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>

最新文章

  1. spring源码分析之定时任务Scheduled注解
  2. C#通过WMI的wind32 的API函数实现msinfo32的本地和远程计算机的系统日志查看功能
  3. Win2008上.NET4.0部署出错HTTP 错误 500.21 - Internal Server Error的解决方法
  4. &lt;转&gt;Npoi导入导出Excel操作&lt;载&gt;
  5. SharePoint自动化系列——创建MMS terms
  6. 51nod 1043 幸运号码(数位dp)
  7. bzoj1036: [ZJOI2008]树的统计Count 树链剖分+线段树
  8. leetcode面试准备: Jump Game II
  9. 【原创】车载实时路况信息接收终端移植于Smart210开发板 --- 综合教程
  10. Wind River Linux 6 Security Profile
  11. Swift初体验(两)
  12. spring框架总结(03)重点介绍(Spring框架的第二种核心掌握)
  13. OAuth2.0学习(1-12)开源的OAuth2.0项目和比较
  14. Springboot 配置cors 跨域的几种方法
  15. Mysql加锁过程详解(4)-select for update/lock in share mode 对事务并发性影响
  16. css布局------上下高度固定,中间高度自适应容器
  17. Prepare paddle in Docker1
  18. MySQL通过Navicat实现远程连接
  19. 启动tomcat时cmd窗口一闪而过
  20. 织梦 列表页 list标签 按照自已设置的方式排序

热门文章

  1. 百倍性能的PL/SQL优化案例(r11笔记第13天)
  2. Cygwin 下的 自动安装工具 apt-cyg
  3. 这些年,在wp平台打拼的日子
  4. IOS 控件器的创建方式(ViewController)
  5. Aizu 2456 Usoperanto (贪心)
  6. Android(java)学习笔记103:Framework运行环境之 Android进程产生过程
  7. Java中ArrayList的对象引用问题
  8. [NOI2007]货币兑换Cash
  9. 十四、MySQL UPDATE 查询
  10. vue.js 四(指令和自定义指令)