Django前后端不分离浅尝
写在前面
一直都写的是前后端分离,当初学php的时候对不分离的形式有一点点印象,这次用Django也试一试,感觉这种不分离的形式起一个网站速度很快很快,比分离的写法简单很多,只可惜Django的教程太少了,自己还是比较喜欢分离的写法,于是在学了半天时间后遂放弃,因此只能称作浅尝。本来感觉java没啥前途不想学springboot的,现在看来还是要转到主流的,学起来也方便很多。
一、环境搭建
1.1 创建项目
使用conda activate conda环境名称
启动环境
使用django-admin startproject 项目名称
创建项目,文件结构如下:
mysite
├── manage.py [管理项目文件,例如:运行、类自动生成数据表]
└── mysite
├── __init__.py
├── settings.py [项目配置文件,例如:连接哪个数据库... ]
├── urls.py [根路由,URL和函数的对应关系 /x1/login ->do_login ]
├── asgi.py [异步运行项目,编写socket,处理网络请求]
└── wsgi.py [同步运行项目,编写socket,处理网络请求]
1.2 快速上手
urls.py
from django.contrib import admin
from django.urls import path
from django.shortcuts import HttpResponse
def login(request):
return HttpResponse("登录页面")
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', login),
]
1.3 快速启动
目录中不能出现中文
网站启动起来,通过浏览器就可以访问。
- 打开终端并进入项目根目录(看到manage.py)
- 执行命令,启动网站
python manage.py runserver 127.0.0.1:8000
或
python manage.py runserver
1.4 APP
一个业务创建一个app,除非是业务很多的大型项目可以创建多个app,可以通俗的理解为模块化。
譬如之前的ctf平台,题目相关的一个app,社区相关的一个app。
在django项目中创建app,在app中编写项目中的具体业务,python manage.py startapp web
。
django_study
├── manage.py [管理项目文件,例如:运行、类自动生成数据表]
└── django_study
├── __init__.py
├── settings.py [项目配置文件,例如:连接那个数据... ]
├── urls.py [根路由,URL和函数的对应关系 /x1/login ->do_login ]
├── asgi.py [异步运行项目,编写socket,处理网络请求]
├── wsgi.py [同步运行项目,编写socket,处理网络请求]
└── templates(可能有)[如果前后端不分离的话,放html模板文件]
└── web
├── __init__.py
├── admin.py [内部后台管理的配置,不要动]
├── apps.py [App名字,不要动]
├── migrations [迁移记录,不要修改他,自动生成]
│ └── __init__.py
├── models.py [数据库,类->SQL语句(ORM)] 【经常使用】
├── tests.py [单元测试,不要动]
├── views.py [视图函数,do_login] 【经常使用】
└── templates(可能有)[如果前后端不分离的话,放html模板文件]
# views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
def login(request):
return HttpResponse("登录页面")
# urls.py
from django.contrib import admin
from django.urls import path
from django.shortcuts import HttpResponse
from web.views import login
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', login),
]
二、初识视图函数
# urls.py
from django.contrib import admin
from django.urls import path
from web.views import login
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', login),
]
# views.py
from django.shortcuts import render
from django.shortcuts import HttpResponse
def login(request):
# ...例如:用户名、密码 -> 数据库校验
return HttpResponse("登录页面")
-
request是什么?用户请求相关的所有内容。
去request中获取用户提交的数据等信息。
-
中间,业务逻辑操作。
-
返回值,返回的什么体现用户浏览器的行为不同。
-
return HttpResponse("登录页面")
-
return render(request, "login.html")
(更常见)# views.py from django.shortcuts import render from django.shortcuts import HttpResponse def login(request): return render(request, "login.html")
-
return redirect("https://www.baidu.com")
-
如果开发中用到了
return render(request, "login.html")
寻找HTML模板:
根目录下的templates中找【优先】
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', ], }, }, ]
根据app的注册顺序,逐一去每个app目录下templates文件夹中寻找【如果上面的没有,就去app里找】【推荐,除公用的属于哪个app的放在哪个中】
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "web.apps.WebConfig" ]
单独app的模板,在app中写; 公共的就在最外层的templates中写HTML模板。
三、初识模板
web框架中都要用到模板的语法,用看的值是动态的。
def user_list(request):
# 1.数据库获取所有的用户列表
data = ["武沛齐", "李立权", "张弛"]
mapping = {"name": "武沛齐", "age": 19, "size": 18}
# 2.打开文件并读取内容
# 3.模板的渲染 -> 文本替换
return render(request, "user_list.html", {"message": "标题来了", "data_list": data, "xx": mapping})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>{{ message }}</h1>
<ul>
{% for item in data_list %}
<li>{{ item }}</li>
{% endfor %}
</ul>
# 不支持<a>{{ data_list[0] }}</a>这种写法
<a>{{ data_list.0 }}</a>
<a>{{ data_list.1 }}</a>
<a>{{ data_list.2 }}</a>
<p>{{ xx.name }}</p>
<p>{{ xx.age }}</p>
<p>{{ xx.size }}</p>
<ul>
{% for item in xx.keys %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<hr/>
<ul>
{% for item in xx.values %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<hr/>
<ul>
{% for k,v in xx.items %}
<li>{{ k }} {{ v }}</li>
{% endfor %}
</ul>
</body>
</html>
四、号码列表案例
- URL访问
- 去数据库获取号码列表
- 页面上展示
# urls.py
from django.contrib import admin
from django.urls import path
from django.shortcuts import HttpResponse
from web import views
urlpatterns = [
path('admin/', admin.site.urls),
path('login/', views.login),
path('user_list/', views.user_list),
path('phone/list/', views.phone_list),
]
# views.py
def phone_list(request):
# 1.获取数据
queryset = [
{"id":1, 'phone':"18611168611", 'city':"北京"},
{"id":2, 'phone':"18611168612", 'city':"上海"},
{"id":3, 'phone':"18611168613", 'city':"广州"},
{"id":4, 'phone':"18611168615", 'city':"山西"},
]
# 2.通过页面渲染返回给用户(表格)
return render(request, "phone_list.html", {"data": queryset})
五、静态文件处理
图片、css、js等。
-
静态文件放在app目录下 static 文件夹中
-
页面中使用
{% load static %} <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="{% static 'bootstrap-3.4.1/css/bootstrap.min.css' %}"> </head> <body> <div class="container"> <h1>号码列表</h1> ... <script src="{% static 'jquery-3.6.0.min.js' %}"></script> <script src="{% static 'bootstrap-3.4.1/js/bootstrap.min.js' %}"></script> </div> </body> </html>
六、登录跳转案例
-
移除
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', ]
-
生成token
<div class="login-box"> <h2>用户登录</h2> <form method="post" action="/login/"> {% csrf_token %} <div class="form-group"> <label>用户名</label> <input type="text" class="form-control" placeholder="请输入用户名" name="user"> </div> <div class="form-group"> <label>密码</label> <input type="password" class="form-control" placeholder="请输入密码" name="pwd"> </div> <button type="submit" class="btn btn-primary">提 交</button> <span style="color: red;">{{ error }}</span> </form> </div>
- 感谢你赐予我前进的力量