文章目录
一、django自带的后台管理系统
1. 建表
1.1 打开myapp下models.py,添加以下内容
from django.db import models
# Create your models here.
class Article(models.Model):
title = models.CharField('标题', max_length=256)
content = models.TextField('内容')
time = models.DateTimeField()
1.2 接下来需要同步数据库,只需要两行命令。
python ./manage.py makemigrations
python ./manage.py migrate
这时候会发现根目录下有一个db.sqlite3的文件,打开是乱码,没错这就是刚刚新建的表。以文本的形式存储在根目录下。还需要一步操作,打开myapp目录下的admin.py,添加如下内容,用后台管理系统来管理刚创建的表。
from django.contrib import admin
from myapp.models import Article
# Register your models here.
class ArticleAdmin(admin.ModelAdmin):
list_display = ['title', 'content', 'time']
admin.site.register(Article, ArticleAdmin)
2. 后台管理系统
django的后台管理系统已经很完善了,我们需要做的就是创建一个账号,登录操作,没有其他了,不需要自己写任何东西。
2.1 创建账号
python manage.py createsuperuser
我的用户名和密码均为:admin
2.2 运行后台
admin的url已经默认存在,直接运行项目即可访问Django后台
python ./manage.py runserver
2.3 登录
在浏览器输入http://127.0.0.1:8000/admin
点击添加
我们来添加一组数据。
二、模版渲染
1. 直接将数据渲染到页面
有了数据就要显示在前端,这就要用到模版渲染,首先需要在渲染模版的时候把数据一起返回,打开 myapp 目录下的 views.py
from django.shortcuts import render
from myapp.models import Article
# Create your views here.
def index(request):
article_list = Article.objects.all()
return render(request, 'index.html', {'article_list': article_list})
templates
目录下的index.html
需要修改如下,这里用到了django的janja2渲染模版的语法。
<html>
<head>
<title>test</title>
</head>
<body>
{% for article in article_list %}
<h1>{{ article.title }}</h1>
<span>{{ article.time }}</span>
<p>{{ article.content }}</p>
{% endfor %}
</body>
</html>
刷新浏览器
2. 数据传递给js
有时候数据需要做一些处理再渲染到页面,这就要先把数据给js,具体操作方法和直接渲染其实差不多。
在index.html
里加上这句代码
<script>
let articleList = {{ article_list | safe }};
console.log(articleList)
</script>
修改views的代码
from django.shortcuts import render
from myapp.models import Article
import json
from django.core import serializers
from django.core.serializers.json import DjangoJSONEncoder
# Create your views here.
def index(request):
article_list = serializers.serialize('python', Article.objects.all())
return render(request, 'index.html', {'article_list': json.dumps(article_list, cls=DjangoJSONEncoder)})
三、数据库
1. 查看当前数据库
django自带的是sqlite数据库
-
在vscode中安装
sqlite
插件
-
右键sqlite数据库,新建查询
-
输入查询内容,使用
.help
查看帮助,.databases
查看数据库,使用.tables
查看表,右键选择运行查询即可看到结果
select * from myapp_article
2. 创建UserInfo数据表
- 在model.py中加入如下代码
class UserInfo(models.Model):
username = models.CharField('用户名', max_length=128)
password = models.CharField('密码', max_length=128)
class Meta:
verbose_name = '用户信息'
verbose_name_plural = '用户信息'
def __str__(self):
return self.username
- 执行如下命令创建数据库
python manage.py makemigrations
python manage.py migrate
- 使用Django后台进行数据管理
在admin.py
目录下加入如下代码
from django.contrib import admin
from myapp.models import UserInfo
admin.site.site_header = '任务管理系统'
class UserInfoAdmin(admin.ModelAdmin):
list_display = ('id', 'username', 'password',)
list_display_links = ('username',)
list_per_page = 50
admin.site.register(UserInfo, UserInfoAdmin)
3. Django rest framework配置
- 安装framework
pip install djangorestframework
# 暂时不装也可以
pip install markdown
# 用于数据筛选
pip install django-filter
在settings中注册framework
INSTALLED_APPS = [
'rest_framework',
]
- 序列化
在app目录下创建serializer.py,添加如下代码
from myapp.models import UserInfo
from rest_framework import serializers
class UserInfoSerializer(serializers.ModelSerializer):
class Meta:
model = UserInfo
fields = "__all__"
- 添加视图
在app目录下的view.py中加入如下代码:
from rest_framework.viewsets import ModelViewSet
from myapp.models import UserInfo
from myapp.serializer import UserInfoSerializer
from django_filters.rest_framework import DjangoFilterBackend
class UserInfoViewSet(ModelViewSet):
queryset = UserInfo.objects.all()
serializer_class = UserInfoSerializer
- 添加路由
在app目录下创建urls.py文件:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from tadmin.views import UserInfoViewSet
router = DefaultRouter()
router.register('UserInfo', UserInfoViewSet, basename='UserInfo')
urlpatterns = [
]
urlpatterns += [
path('', include(router.urls)),
]
- 在项目根目录下的urls中加入如下代码
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include('tadmin.urls')),
]
- 筛选和搜索功能配置
在app根目录下创建filter.py文件
from django_filters import FilterSet, filters
from myapp.models import UserInfo
class UserInfoFilter(FilterSet):
name = filters.CharFilter(field_name='username', lookup_expr='icontains')
class Meta:
model = UserInfo
fields = ('username',)
修改app目录下的view文件:
from myapp.models import UserInfo
from myapp.serializer import UserInfoSerializer
from myapp.filter import UserInfoFilter
from django_filters.rest_framework import DjangoFilterBackend
# Create your views here.
def index(request):
article_list = serializers.serialize('python', Article.objects.all())
return render(request, 'index.html', {'article_list': json.dumps(article_list, cls=DjangoJSONEncoder)})
class UserInfoViewSet(ModelViewSet):
queryset = UserInfo.objects.all()
serializer_class = UserInfoSerializer
filter_class = UserInfoFilter
filter_fields = ['username',]
search_fields = ('username',)
在settings中注册django_filters:
INSTALLED_APPS = [
'django_filters',
]
# REST_FRAMEWORK增加全局过滤配置
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.SearchFilter',
],
}
# 如果可以实现模糊查询,则以下语句可省略
FILTERS_DEFAULT_LOOKUP_EXPR = 'icontains'
- 分页设置
在settings.py中做如下修改
# REST_FRAMEWORK增加全局过滤配置
REST_FRAMEWORK = {
# 设置分页
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
- 自动生成api文档
pip install drf-yasg
在项目文件夹setting.py中做如下修改
INSTALLED_APPS = [
'drf_yasg', # swagger
]
在app的urls.py中做如下修改
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="API平台",
default_version="v1",
description="接口文档",
terms_of_service="",
contact=openapi.Contact(email='[email protected]'),
license=openapi.License(name="BSD License"),
),
public=True
)
router = DefaultRouter()
router.register('UserInfo', UserInfoViewSet, basename='UserInfo')
urlpatterns = [
path('docs/', schema_view.with_ui('swagger',cache_timeout=0), name='schema-swagger-ui'),
]
文档查看文档是否成功,http://127.0.0.1:8000/api/v1/docs/
四、vue前端搭建
1. 在Django项目的根目录下创建前端文件
vue init webpack frontProject
2. 修改src/components/HelloWorld.vue中的代码如下
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<ul>
<li v-for="(user,index) in users" :key="index" style="display: block;">
{{ index }}--{{ user.username }}--{{ user.password }}
</li>
</ul>
<form action="">
用户名:<input type="text" placeholder="user name" v-model="inputUser.username"><br>
密码:<input type="text" placeholder="user password" v-model="inputUser.password"><br>
<button type="submit" @click="userSubmit()">提交</button>
</form>
</div>
</template>
<script>
import { getUsers,postUser } from '../api/api.js';
export default {
name:'hellouser',
data () {
return {
msg:'Welcome to Your Vue.js App',
users:[
{username:'test1',password:'test1'},
{username:'test2',password:'test2'}
],
inputUser:{
"username":"",
"password":"",
}
}
},
methods:{
loadUsers(){},
userSubmit(){}
},
created: function(){
this.loadUsers()
}
}
</script>
五、 前后端联调
1. 利用django-cors-headers
模块解决跨域问题
pip install django-cors-headers
然后在项目settings.py中添加该模块:
INSTALLED_APPS = [
'corsheaders',
]
MIDDLEWARE = [
'corsheaders.middleware.CorsMiddleware', # 需注意与其他中间件顺序,这里放在最前面即可
...
]
# 支持跨域配置开始
CORS_ORIGIN_ALLOW_ALL = True
CORS_ALLOW_CREDENTIALS = True
后端部分完成配置,接下来需要补充一下前端的逻辑,
2. Vue框架请求
Vue框架现在一般都用axios模块进行网络请求,这里沿用这种方式,下面是在前端项目中操作:
- 首先命令行安装axios模块,如果没有安装cnpm就还是用npm安装:
npm install axios
- 为了方便管理api请求的各种逻辑,在前端项目的src目录下创建api目录,然后创建
api.js
和index.js
文件。index.js文件是对axios做配置:
/src/api/index.js
import Vue from 'vue'
import Axios from 'axios'
const axiosInstance=Axios.create({
withCredentials:true
})
axiosInstance.interceptors.request.use((config)=>{
config.headers['X-Requested-With'] = 'XMLHttpRequest'
const regex = /.*csrftoken=([^;.]*).*$/
config.headers['X-CSRFToken'] = document.cookie.match(regex) === null ? null : document.cookie.match(regex)[1]
return config
})
axiosInstance.interceptors.response.use(
response=>{
return response
},
error=>{
return Promise.reject(error)
}
)
Vue.prototype.axios=axiosInstance
export default axiosInstance
api.js
文件是对后端进行请求,可以看到,获取books列表和添加一本book各对应于一个请求:
import axiosInstance from "./index";
const axios = axiosInstance
export const getUsers = () => {
return axios.get(`http://127.0.0.1:8000/api/v1/UserInfo/`)
}
export const postUser = (username, password) => {
return axios.post(`http://127.0.0.1:8000/api/v1/UserInfo/`, {
'username': username, 'password': password
})
}
- 然后更新Login.vue中的处理逻辑:
<template>
<div class="hello">
<h1>{{ msg }}</h1>
<ul>
<li v-for="(user,index) in users" :key="index" style="display: block;">
{{ index }}--{{ user.username }}--{{ user.password }}
</li>
</ul>
<form action="">
用户名:<input type="text" placeholder="user name" v-model="inputUser.username"><br>
密码:<input type="text" placeholder="user password" v-model="inputUser.password"><br>
<button type="submit" @click="userSubmit()">提交</button>
</form>
</div>
</template>
<script>
import { getUsers,postUser } from '../../../api/api.js';
export default {
name:'hellouser',
data () {
return {
msg:'Welcome to Your Vue.js App',
users:[
{username:'test1',password:'test1'},
{username:'test2',password:'test2'}
],
inputUser:{
"username":"",
"password":"",
}
}
},
methods:{
loadUsers(){
getUsers().then(response=>{
this.users=response.data.results
})
},
userSubmit(){
postUser(this.inputUser.username,this.inputUser.password).then(response=>{
console.log(response)
this.loadUsers()
})
}
},
created: function(){
this.loadUsers()
}
}
</script>
至此,一个简单的Django+vue前后端分离项目就已搭建完成,测试添加数据成功
可以看到,列表里面的数据是从后端读取到的,同时前端的提交数据库也能有对应的操作,所以前后端至此是打通了。