后台管理及分页器
django-admin基本使用
django后台管理界面:
要进入django的后台管理界面需要建立一个超级用户:
在终端中输入:
python manage.py createsuperuser
而后需要按照提示输入姓名、邮件地址(可按回车跳过)、密码(这里我的密码是root),而后创建完成,如果报错如下:
django.db.utils.ProgrammingError: (1146, "Table 'dj_temp.auth_user' doesn't exist")
原因是因为数据库dj_temp中没有auth_user这张表,因此需要执行:
python manage.py makemigrations
python manage.py migrates
去创建auth_user表,正确创建超级用户结果如下:
而后执行
python manage.py runserver
打开网站,在客户端后加入:admin/后输入用户名和密码即可:
为了更好地演示admin后台管理功能,这里在项目中创建两个模型,首先在项目中的models.py中创建模型:
from django.db import models
# Create your models here.
from django.db import models
# Create your models here.
class Milk_tea(models.Model):
objects = models.Manager()
shop = models.CharField(max_length=32,verbose_name='店铺名称')#店铺名称
variety = models.CharField(max_length=32,verbose_name='名称')#名称
price = models.IntegerField(verbose_name='价格')#价格
class Meta:
db_table = 'milk_tea'
verbose_name = '奶茶'
verbose_name_plural = verbose_name
def __str__(self):
return self.variety
class Buyer(models.Model):
objects = models.Manager()
name = models.CharField(max_length=32,verbose_name='买家姓名')#买家姓名
age = models.IntegerField(verbose_name='买家年龄')#年龄
milktea = models.ManyToManyField(Milk_tea,through='Relation')#同一奶茶可以有多个买家,一个买家也可以买多个奶茶
class Meta:
db_table = 'buyer'
verbose_name = '买家'
verbose_name_plural = verbose_name
def __str__(self):
return self.name
class Relation(models.Model):
objects = models.Manager()
milktea = models.ForeignKey(Milk_tea,on_delete=models.CASCADE,verbose_name='购买的奶茶ID')
buyer = models.ForeignKey(Buyer,on_delete=models.CASCADE,verbose_name='购买者ID')
class Meta:
db_table = 'MilkTea_buyer_relation'
verbose_name = '购买情况'
verbose_name_plural = verbose_name
这里的verbose_name使得返回中文的参数,而非以变量名称进行返回,在后台管理模式下更好看些。
这里在数据库中创建了三个表,分别存储奶茶信息,以及相应买家信息,以及多对多模式下的购买情况,因此这里对应了多对多的模型。之后终端中执行:
python manage.py makemigrations
python manage.py migrate
创建数据表后需要在项目中的admin.py中创建models列表,将创建的模型类添加进去即可:
from django.contrib import admin
# Register your models here.
from app_temp.models import Milk_tea, Buyer, Relation
models = [
Milk_tea,
Buyer,
Relation,
]
admin.site.register(models)
而后终端中执行:
python manage.py runserver
结果如下:
可以发现这里在后台管理总将项目app_temp添加,并且将创建的三个表添加进后台。
并且通过admin的后台可以查看并且增添修改数据库中的信息:
这里分别在买家中添加了yw的买家,以及购买了书亦烧仙草的茉白:)
django后台管理权限
我们打开Django创建的数据库表,会发现有这么几个数据表:
顾名思义,auth_group,auth_permission通过多对多的关系,构成了auth_group_permission;auth_user,auth_group构成了auth_user_group;auth_user,auth_permission构成了auth_user_user_permission。
我们通过观察admin后台管理中的认证和授权一栏,可以发现添加的用户与组包括权限其实和创建的django数据库是对应的。
下面我们通过创建一个组来进行演示,在认证和授权一栏中添加组:
如上图所示,我们新建了一个组,这里的组可以理解为权限的集合,这里对组起名为只读,添加的权限为Can view两个数据表的内容。
而后我们点击用户,添加刚才创建的组, 其实在组一栏的下方有一个用户权限,可以一条一条的为user添加permission,本质上还是django数据库中的user、group、permission三个两两多对多关系的映射。
点击保存后就只能按照权限浏览信息了。
以上是django后台管理的常规操作介绍。
django分页器
为什么要设置分页器:当客户端是浏览器时,通过设置分页器来管理庞大的数据,一方面能够减少内存的占用,一方面能够美化界面并且能够提高查询效率。
使用方法:
from django.core,paginator import Paginator
#来实例化分页器对象。
paginator = Paginator(数据源,每页最多显示的条数)
实例:这里我们新建一个app叫做app_page,而后在settings.py和总路由urls.py中添加路由信息,而后创建一个数据表进行引用。
# models.py
from django.db import models
# Create your models here.
class Citys(models.Model):
city_name = models.CharField(max_length=32, verbose_name='城市名')
city_from = models.CharField(max_length=32, verbose_name='从属国家')
class Meta:
db_table = '城市'
verbose_name = '城市'
verbose_name_plural = verbose_name
将创建的模型添加进admin.py后在admin后台进行数据添加。
这里我创建了20个城市。
而后我们在models.py的city类下添加一个get_list方法用于获取数据:
@classmethod
def get_list(cls, **kwargs):
filters = {}
return cls.objects.filter(**filters)
而后在views.py下编写视图函数:
def get_list_view(request):
page_num = request.GET.get("page", 1)
citys = Citys.get_list()
paginator = Paginator(citys,PAGE_SIZE)
try:
data = paginator.page(page_num)
except InvalidPage:
data = paginator.page(1)
return render(request, "city.html", {"data": data,"paginator": paginator})
这里的get_list用于获取所有的city数据,通过实例化Paginator来获取页数等信息,通过url传参page,实现任意页数的链接。
相应的html如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>城市分页</title>
</head>
<body>
<table>
<thead>
<tr>
<th>城市名称</th>
<th>来自</th>
</tr>
</thead>
<tbody>
{% for i in data %}
<tr>
<td>{{ i.city_name }}</td>
<td>{{ i.city_from }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<a href="{% url 'app_page:list' %}">首页</a>
{% if data.has_previous %}
<a href="{% url 'app_page:list' %}?page={{ data.previous_page_number }}">上一页</a>
{% else %}
<a href="javascript:alert('没有上一页了')">上一页</a>
{% endif %}
{% if data.has_next %}
<a href="{% url 'app_page:list' %}?page={{ data.next_page_number }}">下一页</a>
{% else %}
<a href="javascript:alert('没有下一页了')">下一页</a>
{% endif %}
<a href="{% url 'app_page:list' %}?page={{ paginator.num_pages }}">末页</a>
</body>
</html>