Django 是一个高级 Python Web 框架,鼓励快速开发和干净、实用的设计。由经验丰富的开发人员构建,它负责处理 Web 开发的大部分麻烦,因此您可以专注于编写应用,而无需重新发明轮子。它是自由和开源的
一、基础知识准备
1 学习路线和环境
操作系统:Ubantu 18.04 编程工具:PyCharm 2019.3.4 环 境:python 3.6 + Django 3.0.5
2 Django-MVT架构
Models
:负责与数据库交互 Views
:负责接收请求、获取数据、返回结果 Templates
:负责呈现内容到浏览器
3 Django-目录结构
二、构建项目
1)Linux 构建项目
1 创建虚拟环境
创建项目是要先进入创建的虚拟环境中
虚拟环境让每一个Python项目有独立的运行环境,具体使用方法请看我另外一篇文章Python虚拟环境 因此最后使用python虚拟环境
mkvirtualenv -p python3 my_django #创建名为my_django的虚拟环境
pip3 install Djiango #下载Django 如果下载失败请将pip更换为国内源
2 创建项目
django-admin startproject <Project_Name>
让我们看看 startproject
创建了些什么:
manage.py
:一种命令行工具,允许你以多种方式与该 Django 项目进行交互。 键入python manage.py help,看一下它能做什么。 你应当不需要编辑这个文件;在这个目录下生成它纯是为了方便。__init__.py
:让 Python 把该目录当成一个开发包 (即一组模块)所需的文件。 这是一个空文件,一般你不需要修改它。settings.py
:该 Django 项目的设置或配置。 查看并理解这个文件中可用的设置类型及其默认值。urls.py
:Django项目的URL设置。 可视其为你的django网站的目录。
3 创建APP
python manage.py startapp <App_Name>
Note:创建app时,必须在项目目录下、
4 运行Django服务器
python manage.py runserver
看到下面页面表示项目创建成功:
5 总结
2)Windows构建项目
虚拟环境让每一个Python项目有独立的运行环境,具体使用方法请看我另外一篇文章Python虚拟环境 因此最后使用python虚拟环境
创建虚拟环境:bug
mkvirtualenv -p python3 bug
pip3 install django #如果下载失败请将pip更换为国内源
或者指定下载对应版本
pip3 install django==3.0.5
#查看Django版本
django-admin --version
创建django项目:bug
选择项目解释器: bug
3)PyCharm构建项目
可以使用PyCharm直接一步到位,但是还是要了解上方命令构建的方式
有可能创建之后,没有自动帮你选好解释器(虚拟环境),你可以自己到设置中配置
三、本地配置
本地配置local_settings会重写默认settings中的配置
1 在setting中写入
try:
from .local_settings import *
except ImportError:
pass
2 创建自己的本地配置
# local_setting.py
LANGUAGE_CODE = 'zh-hans'
TIME_ZONE = 'Asia/Shanghai'
注意:给别人代码时不要给local_setting,里面包含个人的配置
四、URL
path()语法
path(<route>,<view>,[name,**kwargs])
route
:,必选,表示url路径,从URL的端口后面开始匹配。 view
:必选,表示route匹配成功后,需要调用的视图,view必须是个函数,也可以使用类视图,但需要使用as_view()函数。 name
:可选,为url指定一个别名。 **kwags
:可选,可以传递额外的参数—字典。
特别说明:django2.1之前使用的是url(),它使用的是正则,如果你仍然想使用正则表达式在你的route中,你可以使用re_path(),它的用法也path基本完全相同,只是在 配置route时,你需要使用正则表达式的方式。
from django.urls import path
from . import views
urlpatterns = [
path(route='index/',view=views.index,name='index',{'foo':'bar'}),
path('index/', views.index,name='index'),#可以这样简写
]
五、View
在 Django 中,视图(view)对 WEB 请求进行回应,视图就是一个 Python 函数,被定义在 views.py
中 视图接收 reqeust 对象作为第一个参数,包含了请求的信息
from django.http import HttpResponse
def index(request):
return HttpResponse("Hello World!")
说明: 第二行引入 HttpResponse,它是用来向网页返回内容。
- index()函数第一个参数必须是 request,与网页发来的请求有关,request 变量里面包含 get 或 post 的内容,用户浏览器,系统等信息在里面 。
- 函数返回了一个 HttpResponse 对象,最终显示几个字到网页上。
使用render方式渲染模板
from django.shortcuts import render
# 导入数据模型ArticlePost
from .models import ArticlePost
def article_list(request):
# 取出所有博客文章
articles = ArticlePost.objects.all()
# 需要传递给模板(templates)的对象
context = { 'articles': articles }
# render函数:载入模板,并返回context对象
return render(request, 'article/list.html', context)
分析如下:
from .models import ArticlePost
从models.py
中导入ArticlePost
数据类ArticlePost.objects.all()
是数据类的方法,可以获得所有的对象(即博客文章),并传递给articles
变量context
定义了需要传递给模板的上下文,这里即articles
- 最后返回了
render
函数。它的作用是结合模板和上下文,并返回渲染后的HttpResponse对象。通俗的讲就是把context的内容,加载进模板,并通过浏览器呈现。
render
的变量分解如下:
- request是固定的
request
对象,照着写就可以 article/list.html
定义了模板文件的位置、名称context
定义了需要传入模板文件的上下文
视图函数这样就写好了。
六、Model
Field 类型
属性 | 描述 |
AutoField | 一个自动增长的IntegerField,一般不直接使用,Django会自动给每张表添加一个自增的primary key |
BooleanField | True/False,默认的widget 是 CheckboxInput。 |
BinaryField | 存储二进制数据。不能使用 filter 函数获得 QuerySet |
BigIntegerField | 64位整数 |
CharField | 存储字符串。必须有max_length参数指定长度 |
CommaSeparatedIntegerField | 一串由逗号分开的整数。必须有 max_length 参数 |
DateField | 日期 |
DateField.auto_now | 每次执行自动记录当前时间,常作为最近一次修改的时间使用 |
DateField.auto_now_add | 第一次创建的时候添加当前时间,常作为创建时间使用 |
DateTimeField | 日期+时间 常用附加选项和DateField一样。 |
DecimalField | 双精度浮点数 |
EmailField | 加上邮件地址合法性验证的CharField,不需要强制设定 max_length |
FileField | 文件上传,不支持 primary_key 和 unique,否则会报 TypeError 异常。 |
FloatField | float 单精度浮点数 |
ImageField | 加上图片合法性验证功能的FileField,需要安装 PIL 或者 Pillow 模块 |
IntegerField | 整数,默认的组件是TextInput。 |
IPAddressField | IP地址,字符串类型,如 127.0.0.1。默认组件是 TextInput。 |
TextField | 大文本,巨长的文本。默认的组件是Textarea |
URLField | 加了 URL 合法性验证的 CharField。 |
Field 选项
选项 | 描述 |
null | boolean 值,默认为false。TURE=将NULL空值存储到数据库中 |
blank | boolean 值,该字段是否可以为空。如果为假,则必须有值。 |
choices | 元组值,一个用来选择值的2维元组。第一个值是实际存储的值,第二个用来方便进行选择。如SEX_CHOICES=((‘F’,’Female’),(‘M’,’Male’),) |
db_column | string 值,指定当前列在数据库中的名字,不设置,将自动采用model字段名 |
db_index | boolean 值,如果为True将为此字段创建索引 |
default | 给当前字段设置默认值 |
editable | boolean 值,如果为false,admin模式下将不能改写。默认为true |
error_messages | 字典,设置默认的出错信息 |
help_text | admin模式下帮助文档,组件内显示帮助文本。 |
primary_key | 设置当前字段为主键,如果没有设置主键django创建表时会自动id主键 |
radio_admin | 用于 admin 模式下将 select 转换为 radio 显示。 |
unique | boolean值,True=该字段的值必须唯一 |
verbose_name | string类型。设置该字段的另一个名字 |
validators | 有效性检查。无效则抛出 django.core.validators.ValidationError 异常。 |
使用实例
在models.py
中创建
class Articles(models.Model):
title = models.CharField(verbose_name='标题',max_length=20)
author = models.CharField(verbose_name='作者',max_length=20)
content = models.TextField(verbose_name='内容')
def __str__(self): #以title显示
return self.title
class UserInfo(models.Model):
choice = [('male','男'),('female','女')]
username = models.CharField(verbose_name='用户名', max_length=32)
mobile_phone = models.CharField(verbose_name='手机号', max_length=32)
password = models.CharField(verbose_name='密码', max_length=32)
sex=models.CharField(verbose_name='性别',choices=choice,default='male',max_length=32)
在admin.py中注册
from .models import Articles
admin.site.register(Articles)
from .models import UserInfo
class StudentsAdmin(admin.ModelAdmin):
list_display = ['username','mobile_phone','password','sex']
admin.site.register(UserInfo,StudentsAdmin)
生成迁移文件并映射,Django会根据指定的数据库自动生成sql语句
python manage.py makemigrations python manage.py migrate
创建后台用户,创建了才可以登录后台
python manage.py createsuperuser
登录后台(127.0.0.1:8000/admin)就能看到创建的Articles和UserInfo
Meta元数据
属性 | 描述 |
db_table = ‘xxx’ | 修改表名为xxx |
ordering = ‘xxx’ | 按照指定字段xxx排序 |
verbose_name = ‘xxx’ | 设置模型对象的可读的名称,单数名字 |
verbose_name_plural = verbose_name | 设置verbose_name的复数名名字 |
abstract = True | 设置模型类为一个基类 |
permissions = ((‘定义好的权限’, ‘权限说明’),) | 给数据库的表设置额外的权限 |
managed = False | 是否按照django既定的规则来管理模型类 |
unique_together = (‘address’, ‘note’) | 联合唯一键,约束 |
app_label = ‘xxx’ | 定义模型类属于哪一个应用 |
db_tablespace | 定义数据库表空间的名字 |
Meta作为模型的子类 注意缩进
class UserInfo(models.Model):
choice = [('male','男'),('female','女')]
username = models.CharField(verbose_name='用户名', max_length=32)
class Meta:
verbose_name_plural=verbose_name = '信息' #将User Infos在后台显示为信息
ordering = ['id','username'] #以id和username排序 #逆序排的话加个‘-’ eg: -id
db_table = 'students' #修改表明为students,默认名为app名_类名
七、Form
Forms字段基本语法
Field(required=True, widget=None, label=None, initial=None,help_text='', error_messages=None, show_hidden_initial=False,validators=(),localize=False, disabled=False, label_suffix=None)
required: 指定字段是否必填 widget : 字段控件 label : 字段在html中显示的标签 initial : 初始在字段中显示的值 help_text: 在字段后面显示定义的帮助文档 error_messages : 是一个字典,错误提示信息 show_hidden_initial : 显示或隐藏初始值 validators : 表单验证规则 localize : 是否支持本地化 disabled : 是否可用 label_suffix : 重写标签的属性后缀
Field类型
所有的字段都继承自Field对象。
CharField
CharField(max_length=None, min_length=None, strip=True, empty_value='', **kwargs)
IntegerField
IntegerField(max_value=None, min_value=None, **kwargs)
BaseTemporalField
BaseTemporalField(BaseTemporalField)
DurationField
DurationField()
FileField
FileField(max_length=None, allow_empty_file=False, **kwargs)
BooleanField
BooleanField()
ChoiceField
ChoiceField(choices=(),**kwargs)
ComboField
ComboField(fields,**kwargs)
MultiValueField
MultiValueField(fields, *, require_all_fields=True, **kwargs)
继承自Field类型
继续自CharField的字段
RegexField
RegexField(regex, **kwargs)
EmailField
EmailField(**kwargs)
URLField
URLField(**kwargs)
GenericIPAddressField
GenericIPAddressField(protocol='both', unpack_ipv4=False, **kwargs)
SlugField
SlugField(allow_unicode=False, **kwargs)
UUIDField
UUIDField()
继承自IntegerField的字段
FloatField
FloatField()
DecimalField
DecimalField(max_value=None, min_value=None, max_digits=None, decimal_places=None, **kwargs)
继承自BaseTemporalField的字段
TimeField
TimeField()
DateTimeField
DateTimeField()
继承自FileField的字段
ImageField
ImageField()
继承自BooleanField的字段
NullBooleanField
NullBooleanField()
继承自ChoiceField的字段
TypedChoiceField
TypedChoiceField(coerce=lambda val: val, empty_value='', **kwargs)
MultipleChoiceField
MultipleChoiceField()
FilePathField
FilePathField(path, *, match=None, recursive=False, allow_files=True,
allow_folders=False, **kwargs)
继承自ChoiceField的字段
TypedMultipleChoiceField
TypedMultipleChoiceField(coerce=lambda val: val, **kwargs)
widget表单控件
每个Filed字段都有一个默认的widget类型。如果你想要使用一个不同的Widget,可以在定义字段时使用widget参数。 像这样:
from django import forms
class RegisterForms(forms.Form):
password = forms.CharField(widget=forms.PasswordInput)
控件 | 描述 |
TextInput | 对应HTML中的<input type="text"/> |
NumberInput | 数字输入框(为TextInput加数字验证) |
EmailInput | 邮箱输入框(为TextInput加邮箱格式验证) |
URLInput | url输入框 |
PasswordInput | 密码输入框 |
HiddenInput | 隐藏输入框 |
Textarea | 文本区输入框 |
DateInput | 日期输入框 |
DateTimeInut | 日期时间输入框 |
TimeInput | 时间输入框 |
SplitDateTimeWidget | 时间分割框(两个input框) |
RadioSelect | 单选框 |
CheckboxInput | 复选框 |
Select | 单选下拉框 等价ChoiceField |
SelectMultiple | 多选下拉框 等价MultipleChoiceField |
FileInput | 文件上传 |
ClearableFileInput | 多文件上传 |
Form输出选项
- :以表格形式加载表单元素
- :以段落形式加载表单元素
- :以列表形式加载表单元素
使用实例
在app
中新建forms.py
,并添加
from django import forms
class RegisterForms(forms.Form):
username = forms.CharField(min_length=4,max_length=10,label='用户名')
password = forms.CharField(min_length=4,max_length=10,label='密码',widget=forms.PasswordInput)
age = forms.IntegerField(label='年龄',min_value=1,max_value=120)
email = forms.EmailField(label='邮箱')
phone = forms.CharField(min_length=11, max_length=11,label='手机')
在view.py
添加
from .forms import RegisterForms
from django.views import View
class IndexForms(View):
def get(self,request):
forms = RegisterForms()
return render(request,'index.html',{'forms':forms})
在url.py
中添加
path('forms/', views.IndexForms.as_view(),name='forms'),
在templates
中新建index.html
,并添加
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Forms</title>
</head>
<body>
<!--渲染成表格-->
<form action="" method="post">
<table>
{{ forms.as_table }}
</table>
<input type="submit" value="提交">
</form>
<hr>
<!--渲染成段落-->
<form action="" method="post">
{{ forms.as_p }}
</form>
<hr>
<!--渲染成标签-->
<form action="" method="post">
{{ forms.as_ul }}
</form>
</body>
</html>
单选、复选、下拉列表
在forms.py
中添加
from django import forms
class SexChoiceForms(forms.Form):
choices_item=[(1,'男'),(2,'女'),(3,'秘密')]
sex1 = forms.ChoiceField(label='性别',choices=choices_item,initial=1)#下拉列表
sex2 = forms.ChoiceField(label='性别', choices=choices_item,widget=forms.RadioSelect,initial=1)#单选框
sex3 = forms.ChoiceField(label='性别', choices=choices_item,widget=forms.CheckboxSelectMultiple,initial=1)#多选框
sex4 = forms.MultipleChoiceField(label='性别', choices=choices_item,initial=1)#多选框
sex5 = forms.ChoiceField(label='性别', choices=choices_item,initial=1,widget=forms.Select)#下拉列表
sex6 = forms.ChoiceField(label='性别', choices=choices_item, initial=1, widget=forms.SelectMultiple)#多选框
其他配置同上
Postman安装
打开官网直接下载,下载后进入下载目录解压
tar -zxvf Postman-linux-x64-7.22.1.tar.gz
然后拷贝到opt
目录下,并运行
sudo cp Postman /opt/ -r
cd /opt/Postman
./Postman
创建软连接
sudo ln -s /opt/Postman/Postman /usr/bin/postman
创建快捷方式,创建完就能在菜单找到Postman了
$ cat > ~/.local/share/applications/postman.desktop << EOL
heredoc> [Desktop Entry]
heredoc> Encoding=UTF-8
heredoc> Name=Postman
heredoc> Exec=postman
heredoc> Icon=/opt/Postman/app/resources/app/assets/icon.png
heredoc> Terminal=false
heredoc> Type=Application
heredoc> Categories=Development;
heredoc> EOL
八、ModelForm
在forms.py
中添加
class ForbsForms(forms.ModelForm)
class Meta:
model = Forbs
fields = '__all__'
在views.py
中添加
class Indexforbs(view):
def get(self,request):
forms = ForbsForms()
return render(request,'index.html',{'forms':forms}
在urls.py
中添加
path('',view.IndexForbs.as_view(),name='forbs')
给ModelForm加入css样式
password = forms.CharField(label='密码',widget=forms.PasswordInput(attrs={'class':"form-control",'placeholder':"请输入密码"}))
九、mysql数据库
linux安装
sudo apt-get install mysql-server #服务器
sudo apt-get install mysql-client #客户端
widows 安装
请参考:win10安装MySql教程
使用
#linux
service mysql start #启动
service mysql stop #停止
service mysql restart #重启
#windows
cd C:\Program Files\MySQL\MySQL Server 8.0\bin #mysql默认安装目录
net start mysql80 #启动 我的服务器名称是MySQL80
net stop mysql80 #停止
#服务器名称查看:打开【控制面板】,选择【系统和安全】,然后选择【管理工具】,再选择【服务】,找到MySQL
连接
sudo mysql -uroot -p
#默认密码为空,回车就可以,如果不是root用户,必须加sudo,不加会报错,应该为还没设root密码,这是个坑点,下步设完就不加sudo
如果密码不正确或忘记密码
cat /etc/mysql/debian.cnf
#user=debian-sys-maint
#password=cwgoq56yTmCFvZBh
#使用账号debian-sys-maint和对应的password值进行登录
mysql -udebian-sys-maint -pcwgoq56yTmCFvZBh
#成功登录进mysql,然后执行下面步骤↓修改root密码
设置数据库root密码
update mysql.user set authentication_string=PASSWORD('你的密码'),plugin='mysql_native_password';
flush privileges;
exit
service mysql start restart
创建数据库
create database my_db charset='utf8'; #最好使用该方法,修改编码才可以在数据库存中文
create database my_db;
删除数据库
drop database my_db;
常用命令
use my_db #使用my_db数据库
show databases; #显示数据库
show tables; #显示表
select database(); #查看正在使用的数据库
show create database my_db; #显示自己创建的数据库
show create table my_table; #显示自己创建的数据库
desc my_table; #显示表结构
show variables like 'character_set_database'; #查看数据库编码
alter database my_db character set utf8; #修改数据库编码
alter table my_tables character set utf8; #修改表编码
创建表
语法:create table Table_Name (Field_Name Field_Type [condition])
condition | 描述 |
primary key | 是否指定为主键 |
auto_increment | 是否自动增长 |
default | 设置默认值 |
unique | 值是否为唯一的 |
Not null | 不能为空 |
foreign key | 指定关键表的外键 |
mysql> use my_db #使用my_db数据库
Database changed
mysql> create table students(
-> id int primary key auto_increment not null,
-> name varchar(20),
-> age int default 20
-> );
mysql> desc students; #显示表结构
+-------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(20) | YES | | NULL | |
| age | int(11) | YES | | 20 | |
+-------+-------------+------+-----+---------+----------------+
3 rows in set (0.01 sec)
插入数据
insert into students (name,age) values ('jwt',18);
mysql> insert into students (name,age) values ('jwt',18); #插入数据
Query OK, 1 row affected (0.03 sec)
mysql> select * from students; #查看students表
+----+------+------+
| id | name | age |
+----+------+------+
| 1 | jwt | 18 |
+----+------+------+
1 row in set (0.01 sec)
docker部署mysql问题
docker部署时到这样一个问题,开启容器时提示本地3306端口被占用,于是就使用这条命令查了下端口使用情况:
fuser -v -n tcp 3306
发现确实被占用了,于是用
kill -s 9 pid
把占用的进程干掉,再次查看是发现还在占用,于是发现是*本地的MySQL服务* 开着,就通过:
service mysqld stop(5.0版本是mysqld)
service mysql stop(5.5.7版本之后是mysql)
把MySQL服务关掉,发现这时端口3306 已经被释放了
十、Django连接数据库
连接方法
在setting.py
中配置
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'my_db',
'USER': 'root',
'PASSWORD': 'root',
'HOST': 'localhost',
'PORT': '3306'
}
}
下载解释器
- 方法一:
pip3 install pymysql
在__init__.py
中配置添加以下代码来导入pymysql模块指向使用mysql数据库
import pymysql
pymysql.install_as_MySQLdb()
执行完上面操作就成功连接上啦
可能会报如下错误:
raise ImproperlyConfigured('mysqlclient 1.3.13 or newer is required; you have %s.' % Database.__version__)
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.13 or newer is required; you have 0.9.3.
解决方法:
找到Python安装路径下或虚拟环境路径下/home/jwt/.virtualenvs/django/lib/python3.6/site-packages/django/db/backends/mysql/base.py
文件
将下面代码注释掉就可以了
if version < (1, 3, 3):
raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
- 方法二:
```
sudo apt install libmysqlclient-dev
pip install mysqlclient
```
十一、Pycharm连接数据库
如果连接MySQL报错:Server returns invalid timezone. Go to ‘Advanced’ tab and set ‘serverTimezone’ property manually. 服务器返回无效时区。转到“高级”选项卡并手动设置“serverTimezone”属性。
解决办法:
mysql -u root -p
mysql>show variables like '%time_zone%';
mysql>set global time_zone='+8:00';
#每次重启服务都要重新配置一遍。
解决:mysql>set persist time_zone='+8:00';
十二、取用数据库中数据
1 从数据库中获取所有数据
objects.all()
在view.py
中添加
from .models import UserInfo #导入model
def index(request):
userinfo_list = UserInfo.objects.all()#取出所有数据
context = {
'userinfos':userinfo_list,#传给模板
}
return render(request,'index.html',context)
在templates
中新建index.html
来显示获取到的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取UserInfo表中信息</title>
</head>
<body>
{% for userinfo in userinfos %}
<h1> {{ userinfo.username}} ----{{ userinfo.password }}</h1>
{% endfor %}
</body>
</html>
2 从数据库中获取第一条数据
objects.first()
3 从数据库中获取一条数据
objects.get(**kwargs) 只能查询一条数据,查询结果包含多条的话会报错
在view.py
中添加
from .models import UserInfo
def index(request):
context = {
'result':UserInfo.objects.get(username='简简'), #查询jwt的个人信息
}
return render(request,'index.html',context)
在templates
中新建index.html
来显示获取到的数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>获取UserInfo表中信息</title>
</head>
<body>
<h1> {{ result.username}}</h1>
<h1> {{ result.sex}}</h1>
<h1> {{ result.mobile_phone}}</h1>
<h1> {{ result.password}}</h1>
</body>
</html>
4 从数据库中获取匹配数据
objects.filter(**kwargs) 从数据库的取得匹配的结果,返回一个对象列表,如果记录不存在的话,它会返回[]
十三、Django-后台
应用注册
若要把app应用显示在后台管理中,需要在admin.py
中注册。注册有两种方式,普通注册和使用装饰器注册
普通注册方法
打开admin.py文件,如下代码:
from django.contrib import admin
from blog.models import Blog
#Blog模型的管理器
class BlogAdmin(admin.ModelAdmin):
list_display=('id', 'caption', 'author', 'publish_time')
#在admin中注册绑定
admin.site.register(Blog, BlogAdmin)
上面方法是将管理器和注册语句分开。有时容易忘记写注册语句,或者模型很多,不容易对应。
装饰器注册
该方式比较方便,推荐用这种方式。
from django.contrib import admin
from blog.models import Blog
#Blog模型的管理器
@admin.register(Blog)
class BlogAdmin(admin.ModelAdmin):
list_display=('id', 'caption', 'author', 'publish_time')
安装SimpleUi后台
Django自带的后台不太好看,SimpleUi官方介绍说SimpleUi是一个更符合国人审美和使用习惯的一个主题
官方后台与simpleui后台对比
安装
pip install django-simpleui
安装simpleui后,在自己项目的settings.py文件中INSTALLED_APPS的第一行加入simpleui
举个例子🌰:
# Application definition
INSTALLED_APPS = [
'simpleui',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
...
]
修改后台名称
在urls.py或者admin.py 里面添加
from django.contrib import admin
admin.site.site_header = '简简'
admin.site.site_title = '简简 后台管理'
修改logo
在setting.py 里面添加
SIMPLEUI_LOGO = 'logo链接'
详细请看:SimpleUi快速上手
Django Admin后台显示 多对多字段
models代码背景【 tag是多对多字段:一个tag可以对应多个文章,多个tag可以都对应一个文章】
class Tag(models.Model):
name = models.CharField(max_length=20, verbose_name="标签名称")
class Article(models.Model):
tag = models.ManyToManyField(Tag, verbose_name="标签")
admin.py中定义函数
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['add_time','title','category','show_tag']
'''展示文章的所有tag'''
def show_tag(self, obj):
return [t.name for t in obj.tag.all()]
show_tags.short_description = "标签" # 设置后台表头
filter_horizontal = ('tag',) #可选项(文章标签选择时的显示样式)
Django 模板 显示 多对多字段
视图 views.py文件
def Index(request):
"""首页展示"""
# 取出所有博客文章
all_articles = Article.objects.all()
# 需要传递给模板(templates)的对象
context = {'all_articles': all_articles}
# render函数:载入模板,并返回context对象
return render(request, 'index.html',context)
在模板中显示所有标签
{% for article in article.tag.all %} #循环显示所有文章
{% for tag in article.tag.all %} #循环显示一个文章的所有标签
{{tag}}
{% endfor %}
{% endfor%}
参考:https://www.cnblogs.com/xmdykf/p/11403000.html#
Django-utils实现后台图片和图标预览
参考:探索Django utils
利用django.utils.html
转义实现图标预览
1.在model.py
中定义图标预览函数
from django.utils.html import format_html
class Category(models.Model):
icon = models.CharField(max_length=30, default='fas fa-home',verbose_name='菜单图标')
#后台图标预览
def icon_data(self):#要引入Font Awesome Free 5.11.1
return format_html('<i class="{}"></i>',self.icon) #转化为<i class="{self.icon}"></i>
icon_data.short_description = '图标预览'# 设置后台显示表头
2.在admin.py
中注册
@admin.register(Category)
class CategoryAdmin(admin.ModelAdmin):
list_display = ['icon','icon_data']#在列表页显示的条目
list_editable = ['icon'] #在列表页即可修改
利用django.utils.html
转义实现图片预览
1.在model.py
中定义图片预览函数
class Article(models.Model):
title = models.CharField(max_length=50, verbose_name='文章标题')
cover = models.URLField(max_length=200, default='https://i.loli.net/2020/04/23/lJLjEtbs2NFwynQ.jpg', verbose_name='文章封面')
#后台图片预览
def cover_preview(self):
return format_html('<img src="{}" width="200px" height="150px"/>',self.cover,)
cover_preview.short_description = '文章封面预览'
2.在admin.py
中注册
```python @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): #设置要显示在后台列表中的字段 list_display = (‘title’,’cover_preview’,)#【在列表页预览图片】 list_display_links = (‘title’,) #设置哪些字段可以点击进入编辑界面 readonly_fields = (‘cover_preview’,)#只读字段,添加该字段才能在后台编辑页预览封面,否则报错 fieldsets = ( #后台文章编辑页面排版