如果你想想Django入门的话,可以点击链接:
Django官方文档:https://docs.djangoproject.com/zh-hans/2.1/topics/
Django快速入手项目:https://docs.djangoproject.com/zh-hans/2.1/intro/tutorial01/
这个文档只是为了让我在学习的过程中有所记录,所以才写的。我之前读过的一篇关于学习的文章中说,当你能向别人说出来你做了什么的时候,你就真正学会了这个东西。以此为目的我才写了这个教程。
我的前半部分的东西主要参考:https://github.com/phodal/growth-in-action,后半部分就是上面的快速入手项目了,其余的内容参考了一些博客,中间也加入了一些自己的粗浅理解。若有问题,烦请不吝赐教。
1、conda create -n Blog python=3.6 创建一个新的环境
2、source activate Blog 激活虚拟环境
3、conda install Django 安装Django
4、进入PyCharm => Preferences => Project Interpreter => 右边的设置键 Add… => conda Environment => 选择/Anaconda3/envs/Blogs/bin/python3
创建数据库以及数据库基本操作
剩下的操作就是看你Mysql学的啥样了,反正这里我先创建了一个数据库添了个数据进去,在使用命令行的过程中有两点需要注意:
创建用户并授权
修改用户密码:
首先需要知道的一个知识点是:我们的用户信息是在 mysql 数据库下的 user 表,这个表的属性有: User(注意大写),authentication_string(原来是password,据说是5.7之后改为这个了),还有一些其他的属性。
所以修改密码其实就是修改这个表里面的属性:update user set authentication_string=password(“123456”) where User = “testuser”;
在增加数据的时候遇到了这样一个问题:
django.db.utils.OperationalError: (1366, "Incorrect string value: '\\xE9\\x9A\\xBE' for column 'sex' at row 1")
这个表明数据的编码不是utf-8,我们需要进入数据库加入这么一句就可以解决了
alter table Blog.server_babyinfo convert to character set utf8
可是每次创建表格都要修改的话十分麻烦,目前还没有找到创建数据库的时候就修改编码方式的办法
django.db.utils.OperationalError: (1366, "Incorrect string value: '\\xE6\\x96\\x87\\xE7\\xAB\\xA0...' for column 'name' at row 1")
一开始被各种花里胡哨博客的忽悠了,在改各种数据库的配置。结果最后发现跟上面的报错是一样的,所以也想上面一样找到那个出错的name改成utf-8就行了。其中涉及到两个table中有name,也是运行这个sql语句就变成utf-8问题就解决了
alter table Blog.auth_permission change name name varchar(255) character set utf8 collate utf8_unicode_ci not null default '';
但是debug的时候还是有很多知识的:
我是参照博客:https://www.cnblogs.com/gerald-x/p/6913877.html重写了一个mysql的配置文件然后复制到support-files文件夹中,然后重启mysql就把我的数据库编码配置变成了一下情况:
+--------------------------+-----------------------------------------------------------+
| Variable_name | Value |
+--------------------------+-----------------------------------------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | latin1 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/local/mysql-5.7.21-macos10.13-x86_64/share/charsets/ |
+--------------------------+-----------------------------------------------------------+
首先需要修改数据库连接的设置,我使用的mysql的数据库所以就这么用:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'Blog', #你所用的数据库,必须已经给了这个用户这个数据库的权限才行
'USER': '*******', #填你的用户名
'PASSWORD': '********', #填你的密码
'HOST': '127.0.0.1',#本机
'PORT': '3306', #mysql数据库的通用端口
}
}
为了保密你的密码和账户可以这样做:https://blog.csdn.net/lemontan123/article/details/81870430
sudo vim ~/.bashrc
# 在这个文件中添加环境变量并export
export BLOG_PSWD=********* #注意等号前后不要有空格
export BLOG_USER=zyz9740
echo $BLOG_USER
zyz9740
然后简单的conda install pymysql,需要安装这个
然后报错提示没有安装MySQL-python,所以需要安装这个,但是conda install里面没有,改这个用了一上午,我的报错跟他的一样所以我的解决方法参考这个了:https://blog.csdn.net/gaogaorimu/article/details/80903112
报错:
pip3 install mysqlclient
Collecting mysqlclient
Using cached https://files.pythonhosted.org/packages/ec/fd/83329b9d3e14f7344d1cb31f128e6dbba70c5975c9e57896815dbb1988ad/mysqlclient-1.3.13.tar.gz
Complete output from command python setup.py egg_info:
Traceback (most recent call last):
File "" , line 1, in <module>
File "/private/var/folders/w6/l9krf1yd1bb_0t3m5bhw_w500000gn/T/pip-build-5ytzox4k/mysqlclient/setup.py", line 18, in <module>
metadata, options = get_config()
File "/private/var/folders/w6/l9krf1yd1bb_0t3m5bhw_w500000gn/T/pip-build-5ytzox4k/mysqlclient/setup_posix.py", line 60, in get_config
libraries = [dequote(i[2:]) for i in libs if i.startswith('-l')]
File "/private/var/folders/w6/l9krf1yd1bb_0t3m5bhw_w500000gn/T/pip-build-5ytzox4k/mysqlclient/setup_posix.py", line 60, in <listcomp>
libraries = [dequote(i[2:]) for i in libs if i.startswith('-l')]
File "/private/var/folders/w6/l9krf1yd1bb_0t3m5bhw_w500000gn/T/pip-build-5ytzox4k/mysqlclient/setup_posix.py", line 13, in dequote
raise Exception("Wrong MySQL configuration: maybe https://bugs.mysql.com/bug.php?id=86971 ?")
Exception: Wrong MySQL configuration: maybe https://bugs.mysql.com/bug.php?id=86971 ?
----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in /private/var/folders/w6/l9krf1yd1bb_0t3m5bhw_w500000gn/T/pip-build-5ytzox4k/mysqlclient/
解决方法:
brew install mysql-connector-c
# 修改前先备份
cp mysql_config mysql_config_backup
# 修改编辑权限
chmod 777 mysql_config
vi mysql_config
# 修改114行
> # Create options
> libs="-L$pkglibdir"
> libs="$libs -l "
# 修改为
> # Create options
> libs="-L$pkglibdir"
> libs="$libs -lmysqlclient -lssl -lcrypto"
pip install mysqlclient
这样子就将mysqlclient安装到我的虚拟环境Blog中去了(当然有的人可能有疑问就是为什么不安装MySQL-python,这个mysqlclient是给python3用的而且兼容python2.7用的这个MySQL-python)
然后又爆了这样一个错:
这个的原因就是你数据库账户密码搞错了,修改一下就好啦
然后还有这样一个错:
这个是因为pymysql只安装了没有用,需要在setting.py前面添加这两句:
import pymysql
pymysql.install_as_MySQLdb()
然后终于migrate成功了!!!
Django后台操作:
有几点需要注意:
===================== 上午的工作到此结束,吃饭去了 ====================
EATING…
===================== 下午了!我又来了! =============================
将Blog传到自己的git上去:就按照git的官方指导来走一点问题也没有,我是参考的这个教程 https://blog.csdn.net/css_666/article/details/78105958
不过遇到了这个报错:git误区error: failed to push some refs to '[email protected]:
其实就是用README.md初始化掉了哈哈哈哈哈,参考这个:https://blog.csdn.net/uotail/article/details/80211897
============ 后面觉得这个教程有点混乱,所以换了一个,直接看官方教程了 ==============
https://docs.djangoproject.com/zh-hans/2.1/intro/tutorial01/
django-admin startproject Blog:这样就新建了一个项目,项目的架构如下
manage.py
: 一个让你用各种方式管理 Django 项目的命令行工具。你可以阅读 django-admin and manage.py 获取所有 manage.py
的细节。mysite/
目录包含你的项目,它是一个纯 Python 包。它的名字就是当你引用它内部任何东西时需要用到的 Python 包名。 (比如 mysite.urls
).mysite/__init__.py
:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。如果你是 Python 初学者,阅读官方文档中的 更多关于包的知识。mysite/settings.py
:Django 项目的配置文件。如果你想知道这个文件是如何工作的,请查看 Django settings 了解细节。mysite/urls.py
:Django 项目的 URL 声明,就像你网站的“目录”。阅读 URL调度器 文档来获取更多关于 URL 的内容。mysite/wsgi.py
:作为你的项目的运行在 WSGI 兼容的Web服务器上的入口。阅读 如何使用 WSGI 进行部署 了解更多细节。python3 manage.py startapp blogpost:创建一个应用
下面的东西用来记录官方文档中的“语录”来加深理解:
- 在 Django 中,每一个应用都是一个 Python 包
- 函数 include() 允许引用其它 URLconfs。每当 Django 遇到 :func:~django.urls.include 时,它会截断与此项匹配的 URL 的部分,并将剩余的字符串发送到 URLconf 以供进一步处理。(没看懂)
- 这个 migrate 命令检查 INSTALLED_APPS 设置,为其中的每个应用创建需要的数据表,至于具体会创建什么,这取决于你的 mysite/settings.py 设置文件和每个应用的数据库迁移文件(我们稍后会介绍这个)
- 关注一下文件头部的 INSTALLED_APPS 设置项。这里包括了会在你项目中启用的所有 Django 应用。应用能在多个项目中使用,你也可以打包并且发布应用,让别人使用它们。
- 通过运行 makemigrations 命令,Django 会检测你对模型文件的修改(在这种情况下,你已经取得了新的),并且把修改的部分储存为一次 迁移。
- 迁移是 Django 对于模型定义(也就是你的数据库结构)的变化的储存形式 - 没那么玄乎,它们其实也只是一些你磁盘上的文件。如果你想的话,你可以阅读一下你模型的迁移数据,它被储存在 blogpost/migrations/0001_initial.py 里。别担心,你不需要每次都阅读迁移文件,但是它们被设计成人类可读的形式,这是为了便于你手动修改它们。
# migrate是做什么的?
这个 migrate 命令检查 INSTALLED_APPS 设置,为其中的每个应用创建需要的数据表,至于具体会创建什么,这取决于你的 mysite/settings.py 设置文件和每个应用的数据库迁移文件(我们稍后会介绍这个)。这个命令所执行的每个迁移操作都会在终端中显示出来。如果你感兴趣的话,运行你数据库的命令行工具,并输入 \dt (PostgreSQL), SHOW TABLES; (MySQL), .schema (SQLite)或者 SELECT TABLE_NAME FROM USER_TABLES; (Oracle) 来看看 Django 到底创建了哪些表。
修改blogpost/model.py 添加类
修改setting.py中的INSTALLED_APP,添加新加入的model
python3 manage.py makemigrations blogpost:为模型的改变生成迁移文件。
python3 manage.py migrate:实现数据库迁移,也就是将刚才的模型的改变同步到数据库上
# 什么是迁移?
通过运行 makemigrations 命令,Django 会检测你对模型文件的修改(在这种情况下,你已经取得了新的),并且把修改的部分储存为一次 迁移。
迁移是 Django 对于模型定义(也就是你的数据库结构)的变化的储存形式 - 没那么玄乎,它们其实也只是一些你磁盘上的文件。如果你想的话,你可以阅读一下你模型的迁移数据,它被储存在 blogpost/migrations/0001_initial.py 里。别担心,你不需要每次都阅读迁移文件,但是它们被设计成人类可读的形式,这是为了便于你手动修改它们。
# 构建模型需要几步?
改变模型需要这三步:
1. 编辑 models.py 文件,改变模型。
2. 运行 python manage.py makemigrations 为模型的改变生成迁移文件。
3. 运行 python manage.py migrate 来应用数据库迁移。
数据库迁移被分解成生成和应用两个命令是为了让你能够在代码控制系统上提交迁移数据并使其能在多个应用里使用;这不仅仅会让开发更加简单,也给别的开发者和生产环境中的使用带来方便。
####< 管理页面 >
============== 今天到这里了,困了,明天再学 ==================
================== 别忘了 git push =========================
# 什么是视图
Django 中的视图的概念是「一类具有相同功能和模板的"网页"的集合」。
每个视图必须要做的只有两件事:返回一个包含被请求页面内容的 HttpResponse 对象,或者抛出一个异常,比如 Http404 。至于你还想干些什么,随便你。
你的视图可以从数据库里读取记录,可以使用一个模板引擎(比如 Django 自带的,或者其他第三方的),可以生成一个 PDF 文件,可以输出一个 XML,创建一个 ZIP 文件,你可以做任何你想做的事,使用任何你想用的 Python 库。
Django 只要求返回的是一个 HttpResponse ,或者抛出一个异常。
你项目的 TEMPLATES 配置项描述了 Django 如何载入和渲染模板。默认的设置文件设置了 DjangoTemplates 后端,并将 APP_DIRS 设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 "templates" 子目录。这就是为什么尽管我们没有像在第二部分中那样修改 DIRS 设置,Django 也能正确找到 blogpost 的模板位置的原因。
HttpResponse
对象The render() function takes the request object as its first argument, a template name as its second argument and a dictionary as its optional third argument. It returns an HttpResponse object of the given template rendered with the given context.
利用一个快捷函数来处理404问题:
The [`get_object_or_404()`] function takes a Django model as its first argument and an arbitrary number of keyword arguments, which it passes to the [`get()`]function of the model's manager. It raises [`Http404`] if the object doesn't exist.
他等价于:
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist lalala")
# 什么是通用视图
Web 开发中的一个常见情况:根据 URL 中的参数从数据库中获取数据、载入模板文件然后返回渲染后的模板。 由于这种情况特别常见,Django 提供一种快捷方式,叫做“通用视图”系统。
通用视图将常见的模式抽象化,可以使你在编写应用时甚至不需要编写Python代码。
模板:
默认情况下,通用视图 DetailView使用一个叫做
的模板。在我们的例子中,它将使用 "blogpost/question_detail.html"
模板。template_name
属性是用来告诉 Django 使用一个指定的模板名字,而不是自动生成的默认名字。
参数
对于 DetailView
, question
变量会自动提供—— 因为我们使用 Django 的模型 (Question), Django 能够为 context 变量决定一个合适的名字。然而对于 ListView, 自动生成的 context 变量是 question_list
。为了覆盖这个行为,我们提供 context_object_name
属性,表示我们想使用 latest_question_list
。作为一种替换方案,你可以改变你的模板来匹配新的 context 变量 —— 这是一种更便捷的方法,告诉 Django 使用你想使用的变量名。
个人对模板、视图、对象的粗略认识:
1. 对象是在models.py中定义的,在Django里通常被叫做“模型(model)”,定义了一些成员的类型,是储存在数据库中的,作为后端的部分。
2. 前端的部分被“模板(template)”所构造,这就是一个放在template文件下的html文件。他接受从“视图”中传递过来的对象并利用对象进行展示。
3. 所谓的“视图(views.py)”的作用就是向“模板”中传递“模型/对象”以及进行错误处理的一个“中间层”
4. urls.py将url与对应的“视图”连接起来,让用户在访问的时候通过url访问“视图”来获取“模板”的response返回值
![未命名文件 (https://ws3.sinaimg.cn/large/006tNc79gy1fzpq8yrqlwj30rj0rn77k.jpg)](/Users/listener/Downloads/未命名文件 (2).png)
真正不同的地方在于,自动化 测试是由某个系统帮你自动完成的。当你创建好了一系列测试,每次修改应用代码后,就可以自动检查出修改后的代码是否还像你曾经预期的那样正常工作。你不需要花费大量时间来进行手动测试。
我们需要在blogpost/test.py中编写测试代码,测试的代码继承TestCase类
python3 manage.py test blogpost:进行测试
运行的原理:
python manage.py test blogpost
将会寻找 blogpost
应用里的测试代码django.test.TestCase
的一个子类test
开头的方法。test_was_published_recently_with_future_question
方法中,它创建了一个 pub_date
值为 30 天后的 Question
实例。assertls()
方法,发现 was_published_recently()
返回了 True
,而我们期望它返回 False
。测试系统通知我们哪些测试样例失败了,和造成测试失败的代码所在的行号。
报错如下:
Creating test database for alias 'default'...
Got an error creating the test database: (1044, "Access denied for user 'zyz9740'@'localhost' to database 'test_blog'")
分析发现是因为他不能用这个用户创建数据库,应该是我们之间只给了这个用户Blog数据库的所有权限,但是不能新建,所以我们需要给他创建数据库的权限。但是后来发现其他的权限也需要,所以直接进root把所有的权限都给他吧:
mysql> grant all on *.* to zyz9740@localhost;
然后就可以正常运行了
当需要测试的时候,测试用例越多越好¶
貌似我们的测试多的快要失去控制了。按照这样发展下去,测试代码就要变得比应用的实际代码还要多了。而且测试代码大多都是重复且不优雅的,特别是在和业务代码比起来的时候,这种感觉更加明显。
但是这没关系! 就让测试代码继续肆意增长吧。大部分情况下,你写完一个测试之后就可以忘掉它了。在你继续开发的过程中,它会一直默默无闻地为你做贡献的。
但有时测试也需要更新。想象一下如果我们修改了视图,只显示有选项的那些投票,那么只前写的很多测试就都会失败。但这也明确地告诉了我们哪些测试需要被更新,所以测试也会测试自己。
最坏的情况是,当你继续开发的时候,发现之前的一些测试现在看来是多余的。但是这也不是什么问题,多做些测试也 不错。
如果你对测试有个整体规划,那么它们就几乎不会变得混乱。下面有几条好的建议:
对于每个模型和视图都建立单独的 TestClass
每个测试方法只测试一个功能
给每个测试方法起个能描述其功能的名字
LiveServerTestCase
来和 Selenium 这样的工具进行交互。可以在admin.py中添加的功能有如下几个,我们可以用它们来改变后台的外貌:
DIRS
是一个包含多个系统目录的文件列表,用于在载入 Django 模板时使用,是一个待搜索路径
============== 下班啦哈哈哈哈,看晚上又没有心情写了 =======================