Django Web开发入门基础
官方有很详细的文档,但是看过几遍之后如果要翻找还是有点麻烦,本文算作是学习笔记,提取一些关键点记录下来,另附上官方教程 编写你的第一个 Django 应用
注: 文中的指令使用py,是在Windows上,macOS要使用 python3
1. 安装Django
Django 是一个基于 Python 的Web开发框架,安装前可以用下面的命令检查是否安装了 Django,如果已经安装,会显示版本,没有安装会提示没有该模块
py -m django --version
如果没有安装,可以使用下面的命令安装
py -m pip install Django
2. 创建项目
项目就是一个 project,一个项目可以包含多个 app,也可以理解为多个模块,创建项目使用如下命令,其中 mysite 是项目名称:
django-admin startproject mysite
在令窗口中,切到刚刚创建的项目的根目录(有 manage.py),在项目中创建一个app,名字就叫 polls
py manage.py startapp polls
然后修改几个文件
polls/views.py
from django.http import HttpResponsedef index(request):return HttpResponse("Hello World!")
polls/urls.py
from django.urls import path
from . import viewsurlpatterns = [path("", views.index, name="index"),
]
mysite/urls.py
from django.contrib import admin
from django.urls import include, pathurlpatterns = [path("polls/", include("polls.urls")),path("admin/", admin.site.urls),
]
最后启动服务,浏览器访问 http://localhost:8000/polls/
py manage.py runserver
3. 配置语言和时区
项目配置在 mysite/settings.py
语言标识可以在这里查找 Language Identifiers (RFC 3066)
# 语言设置为中文
LANGUAGE_CODE = 'zh-Hans'
时区标识可以在这里查找 List of tz database time zones
# 时区设置为北京时间
TIME_ZONE = 'Asia/Shanghai'
4. 数据库
就使用自带的 SQLite 吧,方便又简单,如果开发商用的Web App,建议使用其他数据库,要进行额外的配置。
(1)创建数据模型
修改 polls/models.py
import datetimefrom django.db import models
from django.utils import timezoneclass Question(models.Model):question_text = models.CharField(max_length=200)pub_date = models.DateTimeField("date published")def __str__(self):return self.question_textdef was_published_recently(self):return self.pub_date >= timezone.now() - datetime.timedelta(days=1)class Choice(models.Model):# Choice属于一个Questionquestion = models.ForeignKey(Question, on_delete=models.CASCADE)choice_text = models.CharField(max_length=200)votes = models.IntegerField(default=0)def __str__(self):return self.choice_text
(2)激活模型
修改 mysite/settings.py,在 INSTALLED_APP 中添加 polls.apps.PollsConfig
INSTALLED_APPS = ["polls.apps.PollsConfig","django.contrib.admin","django.contrib.auth","django.contrib.contenttypes","django.contrib.sessions","django.contrib.messages","django.contrib.staticfiles",
]
(3)创建数据迁移(尚未提交)
py manage.py makemigrations polls
查看创建的迁移使用的SQL语句,下面命令中的 0001 是上面创建迁移时生成的 polls/migrations/0001_initial.py 文件名中的数字
py manage.py sqlmigrate polls 0001
(4)提交迁移
py manage.py migrate
总结起来就三步:修改模型 -> 创建迁移 -> 提交迁移
(5)玩转数据库API
打开交互式窗口
py manage.py shell
>>> from polls.models import Choice, Question >>> Question.objects.all() <QuerySet []> >>> from django.utils import timezone >>> q = Question(question_text="What's new?", pub_date=timezone.now()) >>> q.save() >>> q.id 1 >>> q.question_text "What's new?" >>> q.pub_date datetime.datetime(2012, 2, 26, 13, 0, 0, 775217, tzinfo=datetime.timezone.utc) >>> q.question_text = "What's up?" >>> q.save() >>> Question.objects.all() <QuerySet [<Question: Question object (1)>]>
>>> from polls.models import Choice, Question >>> Question.objects.all() <QuerySet [<Question: What's up?>]> >>> Question.objects.filter(id=1) <QuerySet [<Question: What's up?>]> >>> Question.objects.filter(question_text__startswith="What") <QuerySet [<Question: What's up?>]> >>> from django.utils import timezone >>> current_year = timezone.now().year >>> Question.objects.get(pub_date__year=current_year) <Question: What's up?> >>> Question.objects.get(id=2) Traceback (most recent call last):... DoesNotExist: Question matching query does not exist. >>> Question.objects.get(pk=1) <Question: What's up?> >>> q = Question.objects.get(pk=1) >>> q.was_published_recently() True >>> q = Question.objects.get(pk=1) >>> q.choice_set.all() <QuerySet []> >>> q.choice_set.create(choice_text="Not much", votes=0) <Choice: Not much> >>> q.choice_set.create(choice_text="The sky", votes=0) <Choice: The sky> >>> c = q.choice_set.create(choice_text="Just hacking again", votes=0) >>> c.question <Question: What's up?>>>> q.choice_set.all() <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> >>> q.choice_set.count() 3 >>> Choice.objects.filter(question__pub_date__year=current_year) <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]> >>> c = q.choice_set.filter(choice_text__startswith="Just hacking") >>> c.delete()
5. 创建管理员
输入下面的命令,然后根据提示设置账户名,邮箱,密码
py manage.py createsuperuser
启动服务,浏览器访问 http://127.0.0.1:8000/admin/
py manage.py runserver
修改 polls/admin.py 让管理员可管理数据
from django.contrib import adminfrom .models import Questionadmin.site.register(Question)
管理员登录后
6. 使用 html 模板
(1)创建 HTML 文件
在 polls/ 目录下新建一个 templates 文件夹,在 polls\templates\ 目录下新建一个 polls 文件见,如果新建一个 HTML 文件,比如 index.html,其最终的路径为 mysite\polls\templates\polls\index.html,代码中将使用 polls\index.html
polls\templates\polls\index.html
{% if latest_question_list %}<ul>{% for question in latest_question_list %}<li><a href="{% url 'index' question.id %}">{{ question.question_text }}</a></li>{% endfor %}</ul>
{% else %}<p>No polls are available.</p>
{% endif %}
polls\templates\polls\detail.html
<h1>{{ question.question_text }}</h1>
<ul>
{% for choice in question.choice_set.all %}<li>{{ choice.choice_text }}</li>
{% endfor %}
</ul>
(2)配置 view
修改 polls/views.py
from django.http import HttpResponse
from django.shortcuts import render, get_object_or_404from .models import Questiondef index(request):latest_question_list = Question.objects.order_by("-pub_date")[:5]context = {"latest_question_list": latest_question_list}return render(request, "polls/index.html", context)def detail(request, question_id):question = get_object_or_404(Question, pk=question_id)context = {"question": question}return render(request, "polls/detail.html", context)def results(request, question_id):return HttpResponse("Results")def vote(request, question_id):return HttpResponse("Vote")
(3)配置 url
修改 polls/urls.py
from django.urls import pathfrom . import viewsurlpatterns = [# ex: /polls/path("", views.index, name="index"),# ex: /polls/5/path("<int:question_id>/", views.detail, name="detail"),# ex: /polls/5/results/path("<int:question_id>/results/", views.results, name="results"),# ex: /polls/5/vote/path("<int:question_id>/vote/", views.vote, name="vote"),
]
(4)URL命名空间
当项目存在多个应用时,可能需要借助命名空间来确定url,在应用的 urls.py 中配置 app_name
from django.urls import pathfrom . import viewsapp_name = "polls"
urlpatterns = [# ex: /polls/path("", views.index, name="index"),# ex: /polls/5/path("<int:question_id>/", views.detail, name="detail"),# ex: /polls/5/results/path("<int:question_id>/results/", views.results, name="results"),# ex: /polls/5/vote/path("<int:question_id>/vote/", views.vote, name="vote"),
]
index.html 中添加 app_name:
{% if latest_question_list %}<ul>{% for question in latest_question_list %}<li><a href="{% url 'polls:index' question.id %}">{{ question.question_text }}</a></li>{% endfor %}</ul>
{% else %}<p>No polls are available.</p>
{% endif %}
(5)创建表单
修改 detail.html
<form action="{% url 'polls:vote' question.id %}" method="post">
{% csrf_token %}
<fieldset><legend><h1>{{ question.question_text }}</h1></legend>{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}{% for choice in question.choice_set.all %}<input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}"><label for="choice{{ forloop.counter }}">{{ choice.choice_text }}</label><br>{% endfor %}
</fieldset>
<input type="submit" value="Vote">
</form>
表单中涉及投票页面和投票结果页面,得新增一个 results.html,并修改 views.py
results.html
<h1>{{ question.question_text }}</h1><ul>
{% for choice in question.choice_set.all %}<li>{{ choice.choice_text }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
{% endfor %}
</ul><a href="{% url 'polls:detail' question.id %}">Vote again?</a>
views.py 中修改 results 和 vote 方法
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.urls import reversefrom .models import Question, Choicedef index(request):latest_question_list = Question.objects.order_by("-pub_date")[:5]context = {"latest_question_list": latest_question_list}return render(request, "polls/index.html", context)def detail(request, question_id):question = get_object_or_404(Question, pk=question_id)context = {"question": question}return render(request, "polls/detail.html", context)def results(request, question_id):question = get_object_or_404(Question, pk=question_id)return render(request, "polls/results.html", {"question": question})def vote(request, question_id):question = get_object_or_404(Question, pk=question_id)try:selected_choice = question.choice_set.get(pk=request.POST["choice"])except (KeyError, Choice.DoesNotExist):return render(request, "polls/detail.html",{"question": question,"error_message": "You didn't select a choice."},)else:selected_choice.votes += 1selected_choice.save()return HttpResponseRedirect(reverse("polls:results", args=(question.id,)))
7. 编写测试用例
首先得有个bug,巧了,我们的 polls
应用现在就有一个小 bug 需要被修复:我们的要求是如果 Question 是在一天之内发布的, Question.was_published_recently()
方法将会返回 True
,然而现在这个方法在 Question
的 pub_date
字段比当前时间还晚时也会返回 True(这是个 Bug)。
在 polls\tests.py 中编写测试代码
import datetimefrom django.test import TestCase
from django.utils import timezone
from .models import Questionclass QuestionModelTests(TestCase):def test_was_published_recently_with_future_question(self):"""检测异常:发布时间比当前时间还要晚"""time = timezone.now() + datetime.timedelta(days=30)future_question = Question(pub_date=time)self.assertIs(future_question.was_published_recently(), False)
运行测试(指令是在项目跟目录执行的,该目录有 manage.py)
py manage.py test polls
py manage.py test polls
将会寻找polls
应用里的测试代码- 查找 django.test.TestCase 子类
- 创建一个特殊的数据库供测试使用
- 在类中寻找测试方法——以
test
开头的方法。
相关文章:

Django Web开发入门基础
官方有很详细的文档,但是看过几遍之后如果要翻找还是有点麻烦,本文算作是学习笔记,提取一些关键点记录下来,另附上官方教程 编写你的第一个 Django 应用 注: 文中的指令使用py,是在Windows上,ma…...

Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切(ROI)功能(C#)
Baumer工业相机堡盟工业相机如何通过BGAPI SDK设置相机的图像剪切(ROI)功能(C#) Baumer工业相机Baumer工业相机的图像剪切(ROI)功能的技术背景CameraExplorer如何使用图像剪切(ROI)功…...

LetCode算法题---第2天
注:大佬解答来自LetCode官方题解 80.删除有序数组的重复项Ⅱ 1.题目 2.个人解答 var removeDuplicates function (nums) {let res [];for (let index 0; index < nums.length; index) {let num 0;if (res.includes(nums[index])) {for (let i 0; i < res.length; …...
Leetcode.2571 将整数减少到零需要的最少操作数
题目链接 Leetcode.2571 将整数减少到零需要的最少操作数 rating : 1649 题目描述 给你一个正整数 n n n ,你可以执行下述操作 任意 次: n n n 加上或减去 2 2 2 的某个 幂 返回使 n n n 等于 0 0 0 需要执行的 最少 操作数。 如果 x 2 i x 2^…...

微前端无界 项目使用记录
1预期目标和场景 一个vue框架开发的应用,需要使用另一个系统的页面。 通俗来说,就是在一个web应用中独立的运行另一个web应用 2 技术支持 微前端处理方案:无界 无界官网: https://wujie-micro.github.io/doc/guide/ CSDN 参考…...

CDH 6.3.2升级Flink到1.17.1版本
CDH:6.3.2 原来的Flink:1.12 要升级的Flink:1.17.1 操作系统:CentOS Linux 7 一、Flink1.17编译 build.sh文件: #!/bin/bash set -x set -e set -vFLINK_URLsed /^FLINK_URL/!d;s/.*// flink-parcel.properties FLI…...

基于谷歌Transeformer构建人工智能问答系统
目录 1 项目背景 2 关键技术 2.1 Transeformer模型 2.2 Milvus向量数据库 3 系统代码实现 3.1 运行环境构建 3.2 数据集介绍 3.3 预训练模型下载 3.4 代码实现 3.4.1 创建向量表和索引 3.4.2 构建向量编码模型 3.4.3 数据向量化与加载 3.4.4 构建检索web 3.5 运行结…...

【2023年11月第四版教材】第15章《风险管理》(合集篇)
第15章《风险管理》(合集篇) 1 章节说明2 管理基础2.1 风险的属性2.2 风险的分类★★★2.3 风险成本★★★2.4 管理新实践 3 管理过程4 管理ITTO汇总★★★5 过程1-规划风险管理6 过程2-识别风险6.1 识别风险★★★6.2 数据收集★★★6.3 数据分析★★★…...
python常见面试题四
解释 Python 中的魔术方法 (magic methods)。 答:魔术方法是以双下划线 __ 开头和结尾的方法,用于在特定条件下自动调用。例如,__init__ 是用于初始化对象的魔术方法。 解释 Python 中的装饰器 (decorator)。 答:装饰器是一种特殊…...

stm32无人机-飞行力学原理
惯性导航,是一种无源导航,不需要向外部辐射或接收信号源,就能自主进行确定自己在什么地方的一种导航方法。 惯性导航主要由惯性器件计算实现,惯性器件包括陀螺仪和加速度计。一般来说,惯性器件与导航物体固连…...

Java括号匹配
目录 一、题目描述 二、题解 一、题目描述 给定一个只包括 (,),{,},[,] 的字符串 s ,判断字符串是否有效。 有效字符串需满足: 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭…...

自动化测试-友好的第三方库
目录 mock furl coverage deepdiff pandas jsonpath 自动化测试脚本开发中,总是会遇到各种数据处理,例如MOCK、URL处理、JSON数据处理、结果断言等,也会遇到所采用的测试框架不能满足当前需求,这些问题都需要我们自己动手解…...

基于微信小程序的火锅店点餐订餐系统设计与实现(源码+lw+部署文档+讲解等)
文章目录 前言系统主要功能:具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序(小蔡coding)有保障的售后福利 代码参考源码获取 前言 💗博主介绍:✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计…...

亿图脑图新版本支持思维导图一键生成PPT、音视频等格式,办公提效再升级
近日,国产思维导图软件——亿图脑图MindMaster发布了全新版本V10.9.0,本次亿图脑图的升级给用户带来了极大的惊喜。全新升级的亿图脑图MindMaster不仅支持20格式的文件智能解析成思维导图,还支持思维导图一键生成PPT、音频、视频等内容形式&a…...

Arthas:Java调试利器使用
Arthas:Java调试利器使用 1. Arthas是什么2. Arthas可以解决什么问题Arthas启动方式1. jar启动2. 在线安装 远程连接命令使用- 退出threadclassloaderscsm watchtrace修改日志级别 1. Arthas是什么 Arthas(阿尔萨斯)是阿里开源的一个Java在线分析诊断工具. 2. Arthas可以解决…...

Nuxt 菜鸟入门学习笔记七:SEO 和 Meta 设置
文章目录 SEO 和 Meta默认值useHeaduseSeoMeta 和 useServerSeoMetaComponentsMeta 对象数据类型格式特性响应式 Reactivity标题模板 Title TemplateBody Tags 示例 ExamplesdefinePageMeta动态设置标题动态添加外部 CSS Nuxt 官网地址: https://nuxt.com/ SEO 和 …...

栈(Stack)和队列(Queue)
栈(Stack)和队列(Queue)都是常见的数据结构,用于存储和操作一组元素。 栈是一种后进先出(Last-In-First-Out,LIFO)的数据结构,类似于把元素堆在一起形成的一堆物体&…...
LeetCode 75 part 06 栈
2390.从字符串中移除星号 思路:把元素加入栈中,遇到 * 号直接弹出栈顶元素 class Solution { public:string removeStars(string s) {stack<char>st;for(int i0;i<s.size();i){//字符加入栈,遇到星号弹出栈if(s[i]!*) st.push(s[i…...

19.组合模式(Composite)
意图:将对象组成树状结构以表示“部分-整体”的层次结构,使得Client对单个对象和组合对象的使用具有一致性。 上下文:在树型结构的问题中,Client必须以不同的方式处理单个对象和组合对象。能否提供一种封装,…...

应用在IPM接口隔离领域中的光电耦合器
IPM即Intelligent Power Module(智能功率模块)的缩写,它是通过优化设计将IGBT连同其驱动电路和多种保护电路封装在同一模块内,使电力变换装置的设计者从繁琐的IGBT驱动和保护电路设计中解脱出来,大大降低了功率半导体器件的应用难度ÿ…...

SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...

Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...