Python学习之Day07-08学习(Django网页Web开发)
一、Django概念和特点
Django特点:强大的数据库功能,Admin,优雅的URL,模版系统,缓存系统(内存),国际化
Django模块:urls.py(请求)--->view.py(视图)----->models.py(模型)----->forms.py(图表)----->admin.py(用户)----->setting.py(配置文件)
二、Djang安装和使用
Djago安装
### 准备Python源
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple### 安装django
pip install django## 创建一个django项目
django-admin.exe startproject mysite## 同一个django项目可以创建多个app
python .\manage.py startapp jf2
python .\manage.py startapp jf ## 当有数据需要改变和迁移时,需要执行如下命令### 检测是否有数据变化
python .\manage.py makemigrations### 重新进行权限认证
python .\manage.py migrate## 打开django程序( http://127.0.0.1:8000/)
python .\manage.py runserver## 打开django程序( http://127.0.0.1:8080/)
python .\manage.py runserver 8080## 打开django程序( http://0.0.0.0:8080/)
python .\manage.py runserver 8080## 清空数据
python.exe .\manage.py flush## 设置超级管理员用户
#### username:ce
#### password:awk123!@#python.exe .\manage.py createsuperuser## 使用python操作数据库
python .\manage.py shell
创建的django项目目录
多app项目目录
django程序启动成功
Django使用
创建一个app程序
python.exe .\manage.py startapp learn
修改settings.py文件
打开模块中view.py文件,处理http请求
### 处理http请求
from django.http import HttpResponse
def index(request):return HttpResponse("晚上好!!!!!everyone")
处理url请求(urls.py)
from django.contrib import admin
from django.urls import path
from learn import views as learn_views
urlpatterns = [path('', learn_views.index),# url('^$',learn_views.index)path(r'^admin/', admin.site.urls),
]
后台启动程序
python .\manage.py runserver 8080
启动成功效果图
创建多个方法使用
from django.http import HttpResponse
def index(request):return HttpResponse("晚上好!!!!!everyone")def add(request):x=request.GET['x']y=request.GET['y']z=int(x)+int(y)return HttpResponse(str(z))
修改setting.py文件
from django.contrib import admin
from django.urls import path
from learn import views as learn_views
urlpatterns = [path('', learn_views.index),# url('^$',learn_views.index)path('add/', learn_views.add), ##加入模块path('admin/', admin.site.urls),
]
后台启动程序
python .\manage.py runserver 8888
访问网页即可显示页面 : http://127.0.0.1:8888/add/?x=4&y=10
设置多个函数参数
》》》urls.py文件
from django.contrib import admin
from django.urls import path, re_path
from learn import views as learn_views
urlpatterns = [path('', learn_views.index),# url('^$',learn_views.index)path('add/', learn_views.add), ##加入模块re_path(r'^add2/(\d+)/(\d+)/$', learn_views.add2), ##加入模块path('admin/', admin.site.urls),
]》》》》view.py文件
from django.shortcuts import render# Create your views here.from django.http import HttpResponse
def index(request):return HttpResponse("晚上好!!!!!everyone")def add(request):x=request.GET['x']y=request.GET['y']z=int(x)+int(y)return HttpResponse(str(z))def add2(request,x,y):z=int(x)+int(y)return HttpResponse(str(z))## 访问url:
http://127.0.0.1:8888/add2/66/88/
三、Django 实战入门
-
实战1:学习笔记模块
让用户能够记录学习的兴趣,并在学习每个主题的工程添加日志条目,学习笔记的主页对这个网站进行描述,并邀请用户注册和登录,用户登录后就可以创建新主题,添加新条目及阅读既有的条目
## 创建项目(learning_log)
django-admin.exe startproject learning_log## 创建一个Python内置的数据库
python.exe .\manage.py migrate## 创建数据库
python.exe .\learning_log\manage.py migrateOperations to perform:Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:Applying contenttypes.0001_initial... OKApplying auth.0001_initial... OKApplying admin.0001_initial... OKApplying admin.0002_logentry_remove_auto_add... OKApplying admin.0003_logentry_add_action_flag_choices... OKApplying contenttypes.0002_remove_content_type_name... OKApplying auth.0002_alter_permission_name_max_length... OKApplying auth.0003_alter_user_email_max_length... OKApplying auth.0004_alter_user_username_opts... OKApplying auth.0005_alter_user_last_login_null... OKApplying auth.0006_require_contenttypes_0002... OKApplying auth.0007_alter_validators_add_error_messages... OKApplying auth.0008_alter_user_username_max_length... OKApplying auth.0009_alter_user_last_name_max_length... OKApplying auth.0010_alter_group_name_max_length... OKApplying auth.0011_update_proxy_permissions... OKApplying auth.0012_alter_user_first_name_max_length... OKApplying sessions.0001_initial... OK## 启动django服务
python .\manage.py runserver## 创建应用
python .\manage.py startapp learning_logs ## 定义数据库(models.py)from django.db import models# Create your models here.
class Topic(models.Model):''' 用户学习的主题 '''text=models.CharField(max_length=200) ## 存储文本内容data_added=models.DateTimeField(auto_now_add=True) ### 自动设置模型时间def __str__(self):'''返回model字符串表示'''return self.text## 激活models(setting.py)
#### 编辑INSTALLED_APPS添加我们的app 生成数据迁移文件
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','learning_logs'
]python .\manage.py makemigrations learning_logs ### 执行数据库的变更
python.exe .\manage.py migrateOperations to perform:Apply all migrations: admin, auth, contenttypes, learning_logs, sessions
Running migrations:Applying learning_logs.0001_initial... OK
数据库修改的三个步骤1. 修改models.py文件2. makemigrations+appname (python manage.py makemigrations learning_logs)3. migrate (Python manage.py migrate)
使用Admin管理网站
1.创建超级用户
python.exe .\manage.py createsuperuser ### python字符串存储的是密码的散列值
########### 用户名 admin ###################### 密码 admin ############## 修改admin.py文件from django.contrib import admin
# Register your models here.
from learning_logs.models import Topic
admin.site.register(Topic) ### 通过admin管理模型
2.访问后台页面
http://127.0.0.1:8000/admin/login/?next=/admin/
3.后台topic,即对应字符串返回内容
def __str__(self):'''返回model字符串表示'''return self.text
4.增加数据源文件(models.py)
### 增加model模型
from django.db import models# Create your models here.
class Topic(models.Model):''' 用户学习的主题 '''text=models.CharField(max_length=200) ## 存储文本内容data_added=models.DateField(auto_now_add=True) ### 自动设置模型时间def __str__(self):'''返回model字符串表示'''return self.text# return "Fuck"class Entry(models.Model):'''学校主题的某个知识'''topic =models.ForeignKey(Topic)text=models.TextField()data_added=models.DateTimeField(auto_now_add=True)class Meta:verbose_name_plural='entries'def __str__(self):return self.text[:50]+'....'### 更新修改的数据源
python .\manage.py makemigrations learning_logs
python manage.py migrate ### 修改admin.py文件
from django.contrib import admin
# Register your models here.from learning_logs.models import Topic,Entryadmin.site.register(Topic) ### 通过admin管理模型
admin.site.register(Entry) ### 通过admin管理模型## 启动django
python.exe .\manage.py runserver
笔记目录功能创建成功
根据python shell可以查看和调试所创建的topic数据(这些业务逻辑写在view层即可)
## 进入python-shell控制管理页面
python manage.py shell
>> from learning_logs.models import Topic### 获取对象中的数据
>> Topic.objects.all()
<QuerySet [<Topic: Python>, <Topic: halo>, <Topic: Python字典>, <Topic: python列表>]>>> t=Topic.objects.all()>>> for i in t:
... print(i.id,i)
...
1 Python
2 halo
3 Python字典
4 python列表>>> t=Topic.objects.get(id=1)
>>> print(t.text)
Python#### 获取时间戳中的时间
>>> t.data_added
datetime.datetime(2025, 10, 6, 16, 17, 15, 382163, tzinfo=datetime.timezone.utc)### 获取所创建的对象(key,value)
>>> t.entry_set.all()
<QuerySet [<Entry: 字典(Dictionary)
字典是一个无序、可变和有索引的集合。在 Python 中,字典用花括....>, <Entry: 字典(Dictionary)
字典是一个无序、可变和有索引的集合。在 Python 中,字典用花括....>]>### 获取python内置数据库sqllite内容
>> python manage.py sqlmigrate learning_logs 0001_initial BEGIN;
--
-- Create model Topic
--
CREATE TABLE "learning_logs_topic" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "text" varchar(200) NOT NULL, "data_added" datetime NOT NULL);
COMMIT;
使用Django创建网页过程
层级架构如下
定义url---->编写view----->编写模版
### 定义url(urls.py)
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls), ## include引入文件 (导入配置文件进行映射)path('', include('learning_logs.urls')),
]### urls.py
### 定义learning_log 的Url Pattrernsfrom django.urls import path ## 导入django配置文件
from . import views ## 引入当前目录下的view文件urlpatterns=[## 主页path('', views.index, name='index'), ## 可以根据name名字匹配目标URL]### 修改views.py文件
from django.shortcuts import render# Create your views here.def index(request):'''学习笔记主页'''return render(request, 'learning_logs/index.html')### 创建视图 模版文件
mkdir templates;cd templates;mkdir learning_logs;cd learning_logs;touch index.html<p>learning log</p>
<p>学习笔记可以帮助你追踪学习的情况</p>
查看后台视图
给网页创建多个模版
### 修改urls.py文件### Python 2.0 以上版本
from django.urls import path
from . import viewsapp_name = 'learning_logs' # 这行是关键!
urlpatterns = [path('', views.index, name='index'), ### name:调用url地址
]### 父模板添加如下配置)(base.html)
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><p><a href="{% url 'learning_logs:index' %}">学习笔记</a></p>
<!-- 所定义的父模板 -->{% block content %}{% endblock content %}
</body>
</html>### 子模板添加如下内容(index.html)
{% extends "learning_logs/base.html" %}
{% block content %}
<p>learning log</p>
<p>学习笔记可以帮助你追踪学习的情况</p>
{% endblock %}
开发显示主题模块
###修改urls.py文件app_name = 'learning_logs' # 这行是关键!
urlpatterns = [''' 主页 ''',path('', views.index, name='index'), ### name:调用url地址''' 显示所有的主题 ''',path('topics/',views.topics,name='topics')
]### 在views.py文件中加入配置
from django.shortcuts import render
from .models import Topic
# Create your views here.def index(request):'''学习笔记主页'''return render(request, 'learning_logs/index.html')def topics(request):'''显示所有主题'''topics=Topic.objects.all()context={'topics':topics}return render(request,'learning_logs/topics.html',context)### 创建模版文件(topics.html)
{% extends "learning_logs/base.html" %}{% block content %}
<p>Topics</p>
<ul>{% for topic in topics %}<li>{{ topic }}</li>{% empty %}<li> 没有创建任何主题 </li>{% endfor %}
</ul>
{% endblock content %}### 修改父模版文件
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><p><a href="{% url 'learning_logs:index' %}">学习笔记</a><a href="{% url 'learning_logs:topics' %}">Topics</a> ### 添加topic主题</p>
<!-- 所定义的父模板 -->{% block content %}{% endblock content %}
</body>
</html>
数据已经被取到后展示效果
根据所给主题查看主题内容
#### 创建url.py文件
from django.urls import path
from . import viewsapp_name = 'learning_logs' # 这行是关键!
urlpatterns = [## 主页path('', views.index, name='index'), ### name:调用url地址##显示所有的主题path('topics/',views.topics,name='topics'),## 根据top_id查看指定主题内容# path('topics/<(?P:topic_id>\d+)/$', views.topic, name='topic')path('topics/<int:topic_id>/', views.topic, name='topic')
]### 添加topic业务(view.py)def topic(request, topic_id):topic=Topic.objects.get(id=topic_id)entries=topic.entry_set.order_by('-date_added') ## 对topic条目进行降序排序context={ 'topic':topic, 'entries':entries }return render(request,'learning_logs/topic.html',context)### 创建模板html文件(topic.html)
{% extends "learning_logs/base.html" %}{% block content %}
<p>Topic</p>
<p>Topic{{topic}}</p>
<p>Entries</p>
<ul>{% for entry in entries %}<li><p>{{ entry.date_added | date:'M,D,Y H:i' }}</p><p>{{ entry.text|linebreaks }}</p></li>{% empty %}<li>没有创建任何条目</li>{% endfor %}
</ul>
{% endblock content %}
列表内容展示后的效果如下
实战2:用户账户模块
-
新增主题和条目模块
######### 新增表单 #########
### 创建表单(form.py)from django import forms
from .models import Topicclass TopicForm(forms.ModelForm):class Meta:model=Topicfields=['text']labels={'text':''}### 添加url.py请求## 创建表单path('new_topic/', views.new_topic, name='new_topic')### 在原topic.html页面添加如下内容
<a href="{% url 'learning_logs:new_topic' %}">新建主题</a>### 添加模版文件
{% extends "learning_logs/base.html" %}{% block content %}<p>新建主题</p>
<form action="{% url 'learning_logs:new_topic' %}" method='post'>
<!-- 防止攻击-->{% csrf_token %}{{ form.as_p }}<button name="submit">提交</button></form>{% endblock content %}######### 新增表单实例 ############ 添加表单数据 表单(form.py)
class EntryForm(forms.ModelForm):class Meta:model=Entryfields=['text']labels={'text':''}widgets={'text':forms.Textarea(attrs={'cols': 80})} ## 给表单指定宽度## 添加urlpattern## 表单实例path('new_entry/<int:topic_id>/', views.new_entry, name='new_entry')## 创建表单函数
def new_entry(request,topic_id):topic=Topic.objects.get(id=topic_id)if request.method != 'POST':form = EntryForm()else:form = EntryForm(data=request.POST)if form.is_valid():new_entry=form.save(commit=False)new_entry.topic=topicnew_entry.save()return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic_id]))context={'topic':topic,'form':form}return render(request,'learning_logs/new_entry.html',context)## topics.html添加如下内容
<a href="{% url 'learning_logs:new_topic' %}">新建主题</a>## 创建模版html文件(new_entry.html)
{% extends "learning_logs/base.html" %}{% block content %}<p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a><p>添加新条目</p><form action="{% url 'learning_logs:new_entry' topic.id %}" method="post">{% csrf_token %}{{ form.as_p }}<button name="submit">提交</button></form>
</p>{% endblock content %}
完成后效果图如下
修改条目数据
### 编写url(urls.py)path('edit_entry/<int:entry_id>/',views.edit_entry,name='edit_entry')## 编写view.py逻辑
def edit_entry(request,entry_id):entry=Entry.objects.get(id=entry_id)topic=entry.topicif request.method!='POST':form = EntryForm(instance=entry) ## 将实例装入表格中else:form=EntryForm(instance=entry,data=request.POST)if form.is_valid():form.save()return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))context={'entry':entry,'topic':topic,'form':form}return render(request,'learning_logs/edit_entry.html',context)## 编写edit_entry.html
{% extends "learning_logs/base.html" %}{% block content %}<p><a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
</p>
<p>编辑条目</p>
<form action="{% url 'learning_logs:edit_entry' entry.id %}" method="post">{% csrf_token %}{{ form.as_p }}<button name="submit">保存</button>
</form>
{% endblock content %}
展示后的效果如下
创建用户
用户登录逻辑
### 创建一个app ###
python manage.py startapp users### 编辑setting.xml文件
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth','django.contrib.contenttypes','django.contrib.sessions','django.contrib.messages','django.contrib.staticfiles','learning_logs','users'
]## 修改url.py文件from django.urls import path
from django.contrib.auth.views import LoginViewapp_name = 'users' # 这行很重要
urlpatterns = [path('login/', LoginView.as_view(template_name='users/login.html'), name='login'),
]## 添加url地址
from django.contrib import admin
from django.urls import path, includeapp_name = 'learning_logs' # 必须要有这行!
urlpatterns = [path('admin/', admin.site.urls),path('users/', include('users.urls')),path('', include('learning_logs.urls')),]## 修改login.html页面
{% extends "learning_logs/base.html" %}{% block content %}{% if form.error %}<p>用户名和密码不匹配,请重试!</p>{% endif %}<form method="post" action="{% url 'users:login' %}">{% csrf_token %}{{ form.as_p }}<button name="submit">登录</button><input type="hidden" name="next" value="{% url 'learning_logs:index' %}" /></form>
{% endblock content %}## 修改base.html<p><a href="{% url 'learning_logs:index' %}">学习笔记</a><a href="{% url 'learning_logs:topics' %}">Topics</a>{% if user.is_authenticated %}您好 {{ user.username}}{% else %}<a href="{% url 'users:login' %}">登录</a>{% endif %}</p>
用户注销逻辑
## 打开urls.py文件 from django.urls import path
from django.contrib.auth.views import LoginView
from . import views
app_name = 'users' # 这行很重要
urlpatterns = [path('login/', LoginView.as_view(template_name='users/login.html'), name='login'),path('logout/', views.logout_view,name='logout'),
]## 打开view.py文件
from django.shortcuts import render
from django.http import HttpResponseRedirectfrom django.contrib.auth import logout
from django.urls import reverse# Create your views here.def logout_view(request):logout(request)return HttpResponseRedirect(reverse('learning_logs:index'))### base.html文件<p><a href="{% url 'learning_logs:index' %}">学习笔记</a><a href="{% url 'learning_logs:topics' %}">Topics</a>{% if user.is_authenticated %}您好 {{ user.username}}<a href="{% url 'users:logout' %}">注销</a>{% else %}<a href="{% url 'users:login' %}">登录</a>{% endif %}</p>
用户注册逻辑
## 修改urls.py
from django.urls import path
from django.contrib.auth.views import LoginView
from . import views
app_name = 'users' # 这行很重要
urlpatterns = [path('login/', LoginView.as_view(template_name='users/login.html'), name='login'),path('logout/', views.logout_view,name='logout'),## 注册逻辑path('register/', views.register, name='register'),
]## 用户注册逻辑
def register(request):'''注册新用户'''if request.method != 'POST':form= UserCreationForm()else:## 处理填写好的表单form = UserCreationForm(data=request.POST)if form.is_valid():new_user=form.save()## 让用户自动登录,再重定向到主页authenticated_user=authenticate(username=new_user.username,password=request.POST['password1'])login(request,authenticated_user)return HttpResponseRedirect(reverse('learning_logs:index'))context={'form':form}return render(request,'users/register.html',context)## 修改register.html
{% extends "learning_logs/base.html" %}
{% block content %}<form method="post" action="{% url 'users:register' %}">{% csrf_token %}{{ form.as_p }}<button name="submit">register</button><input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
</form>{% endblock content %}## 修改模版base.html
{% if user.is_authenticated %}您好 {{ user.username}}<a href="{% url 'users:logout' %}">注销</a>{% else %}<a href="{% url 'users:register' %}">注册</a>-<a href="{% url 'users:login' %}">登录</a>{% endif %}
如果用户需要登录,我们此时可以引入 @login_required 完成验证登录
### 配置view.py文件
## 当用户登录未登录会自动跳转到登录界面
@login_required
def topics(request):'''显示所有主题'''topics=Topic.objects.all()context={'topics':topics}return render(request,'learning_logs/topics.html',context)### 配置setting.py文件
LOGIN_URL = '/users/login/'
限制用户登录
限制用户主题登录
### 修改models.py文件(topic类)
owner=models.ForeignKey(User,on_delete=models.CASCADE)## 使用pyhon-shell命令行行窗口python .\manage.py shell## 进入数据源管理(数据迁移工具)
python .\manage.py makemigrations learning_logs It is impossible to add a non-nullable field 'owner' to topic without specifying a default. This is because the database needs something to populate existing rows.
Please select a fix:1) Provide a one-off default now (will be set on all existing rows with a null value for this column)2) Quit and manually define a default value in models.py.
Select an option: 1>>> 1
Migrations for 'learning_logs':learning_logs\migrations\0004_topic_owner.py+ Add field owner to topic### 保存数据源
python .\manage.py migrate
Operations to perform:Apply all migrations: admin, auth, contenttypes, learning_logs, sessions
Running migrations:Applying learning_logs.0004_topic_owner... OK## 回到python-shell窗口,查看文件权限情况
>>> from learning_logs.models import Topic
>>> for topic in Topic.objects.all():
... print(topic,topic.owner)
...
Python admin
halo admin
Python字典 admin
python列表 admin
666 admin
0666 admin
>>>### 数据重建工具
python .\manage.py flush ## 修改view.py逻辑(让创建内容与用户一一对应)
topics=Topic.objects.filter(owner=request.user).order_by('data_added')
数据校验截图如下
test用户下主题情况
admin用户下主题情况
限制url登录
访问url还是能以自身身份访问网页
如果出现异常访问抛出404异常(view.py文件)
def topic(request, topic_id):topic=Topic.objects.get(id=topic_id)if topic.owner !=request.user: ## 设置404权限认证raise Http404entries=topic.entry_set.order_by('-date_added') ## 对topic条目进行降序排序context={ 'topic':topic, 'entries':entries }return render(request, 'learning_logs/topic.html',context)@login_required ###添加权限认证
def new_topic(request):'''添加新主题'''if request.method != 'POST':form = TopicFormelse:form = TopicForm(request.POST)## 检查数据的合法性if form.is_valid():form.save()return HttpResponseRedirect(reverse('learning_logs:topics'))context={'form':form}return render(request,'learning_logs/new_topic.html',context)### 将数据与用户进行绑定关联@login_required
def new_topic(request):'''添加新主题'''if request.method != 'POST':form = TopicFormelse:form = TopicForm(request.POST)## 检查数据的合法性if form.is_valid():# form.save()### 将数据存放到new_topic中new_topic=form.save(commit=False)new_topic.owner=request.usernew_topic.save()return HttpResponseRedirect(reverse('learning_logs:topics'))context={'form':form}return render(request,'learning_logs/new_topic.html',context)