我试着学习了Django教程
编写你的第一个Django应用程序,第一部分¶
首先,我被卡在了无法使用 django-admin 的问题上。虽然有人说只需通过 pip install django 安装就行,但实际上没用。原来必须预先安装 virtualenv。
python3 -m venv venv
. venv/bin/activate
pip install django
django-admin version
因为已准备就绪,所以继续进行原版教程的学习。
$ python -m django --version
3.1.6
$ django-admin startproject mysite
$ ll
total 4.0K
drwxr-xr-x 4 user1 user1 32 2021-02-05 14:38:27 .
drwxrwxrwx 17 user1 user1 4.0K 2021-02-05 14:11:33 ..
drwxr-xr-x 3 user1 user1 37 2021-02-05 14:38:21 mysite
drwxr-xr-x 5 user1 user1 100 2021-02-05 14:34:16 venv
认真地学习教程,并了解文件结构。
manage.py
mysite/
__init__.py
settings.py
urls.py
asgi.py
wsgi.py
我关注的地方是…项目的形式。
我现在创建了一个名为mysite的项目,这是一个应用程序,对吗?
mysite/settings.py: 这个Django项目的设置/配置文件。Django的设置文件将向您介绍所有关于设置的工作方式的信息。
settings.py是mysite的设置文件。但是manage.py属于root目录。
跟我想的有点不一样。
ASGI、WSGI是关于Web服务器的问题吗?我不太清楚,所以暂时跳过。
运行命令 “python manage.py runserver”。
出现了无数次错误。
django.core.exceptions.ImproperlyConfigured: 需要SQLite 3.8.3或更高版本(发现3.7.17)。
好的,这是一个数据库。
编写您的第一个Django应用程序,第2部分
数据库
DB的设置在这里:https://docs.djangoproject.com/en/3.1/ref/databases/#mysql-notes。
CREATE DATABASE django CHARACTER SET utf8;
CREATE USER 'django'@'%' IDENTIFIED WITH mysql_native_password AS '***';
GRANT ALL PRIVILEGES ON *.* TO 'django'@'%' REQUIRE NONE WITH GRANT OPTION MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
CREATE DATABASE IF NOT EXISTS `django`;
GRANT ALL PRIVILEGES ON `django`.* TO 'django'@'%';GRANT ALL PRIVILEGES ON `django\_%`.* TO 'django'@'%';
- settings.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'OPTIONS': {
'read_default_file': '/kc/my.cnf',
},
}
}
我的.cnf
[client]
database = db.example.com
user = django
password = django
default-character-set = utf8
在Python环境中,使用pip安装mysqlclient。
因为完全不看我的.cnf文件,所以我直接修改了。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'django',
'USER': "django",
'PASSWORD': "django",
'HOST': "db.example.com",
'PORT': 3306,
'OPTIONS': {
'sql_mode': 'STRICT_TRANS_TABLES',
'charset': 'utf8mb4',
'init_command': 'SET '
'character_set_connection=utf8mb4,'
'collation_connection=utf8_general_ci'
}
}
}
运行命令 python manage.py migrate
MySQL > 显示表;
+—————————-+
| Tables_in_django |
+—————————-+
| auth_group |
| auth_group_permissions |
| auth_permission |
| auth_user |
| auth_user_groups |
| auth_user_user_permissions |
| django_admin_log |
| django_content_type |
| django_migrations |
| django_session |
+—————————-+
共 10 行(0.07 秒)
完成了!
运行服务器
运行命令 “python manage.py runserver”。
可以在浏览器上看到!
安装成功了!恭喜!
现在你的环境已经设置好了,一个“项目”,你可以开始工作了。
嗯。现在这个指的是一个”项目”吗?
我的网站下面的mysite是什么东西。
python manage.py startapp polls
按照教程的指示创建文件。由于之前没有 polls/urls.py 这个文件,所以我创建了它。
以下的中文翻譯如下:有趣的是
每当Django遇到include()函数时,它会截取与之前相匹配的URL的部分,并将剩下的字符串发送给包含的URLconf以进行进一步处理。
而且只写了一个 path(”) ,却被识别为 /polls。
只有了解Django,才能做到这一点。能够直观地实现是非常棒的。
撰写关于调查的模型
类型错误:init()缺少一个必需的位置参数’on_delete’,因此更改后成功通过。
class Choise(models.Model):
question = models.ForeignKey(
Question,
on_delete=models.CASCADE
)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
运行命令 “python manage.py makemigrations polls” 后,会生成以下文件:polls/migrations/0001_initial.py
原文: sqlかと思ったらpythonなんだな。
Paraphrased: 我以为是sql,原来是python啊。
operations = [
migrations.CreateModel(
name='Question',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('question_text', models.CharField(max_length=200)),
('pub_date', models.DateTimeField(verbose_name='date published')),
],
),
是不是指的是创建模型的事情呢,可能是初始创建吧。
那么,就可以预览一下SQL的内容了。如果无法直接将其迁移到生产环境(如PaaS等情况),可以直接将这个SQL语句传送到数据库中即可!
$ python manage.py sqlmigrate polls 0001
]--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choise
--
CREATE TABLE `polls_choise` (`id` integer AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` integer NOT NULL);
ALTER TABLE `polls_choise` ADD CONSTRAINT `polls_choise_question_id_4bd8457d_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);
这个还没有在数据库中做出任何更改。
只执行迁移操作,表就创建好了!
$ python manage.py migrate
Operations to perform:
Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
Applying polls.0001_initial... OK
我立即发现了一个拼写错误,把Choice误写成了Choise,所以进行了修改。
修改models.py文件一个字符。
class Choice(models.Model):
question = models.ForeignKey(
Question,
on_delete=models.CASCADE
)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
python manage.py makemigrations
python manage.py sqlmigrate polls 0002
python manage.py migrate
仅需这样一个命令:RENAME TABLE polls_choise TO polls_choice; 就可以完成执行!!!太方便了!真是太方便了!!!
使用manage.py打开shell界面
这个调试工具看起来很方便!当SQL不通过时,用这个工具来尝试似乎会很好。虽然一直到django.setup()都有点烦人,但也没办法。
$ python manage.py shell
>>> import django
>>> django.setup() <-----ここまで決り文句
>>>
>>> from polls.models import Question, Choice <-----使うtable/model
>>> Question.objects.all()
<QuerySet []>
# insert
>>> from django.utils import timezone
>>> q = Question(question_text="What's new?", pub_date=timezone.now())
>>> q.save
<bound method Model.save of <Question: Question object (None)>>
>>> q.save()
# insertされたPKがそのままのobjectで見れる!
>>> q.id
1
>>> q.question_text
"What's new?"
>>> q.pub_date
datetime.datetime(2021, 3, 9, 4, 42, 28, 899072, tzinfo=<UTC>)
# updateしてみる
>>> q.question_text = "What's up"
>>> q.save()
>>> Question.objects.all()
<QuerySet [<Question: Question object (1)>]>
只知道pk=1的话很不方便,我想知道这里的!
给模型加上字符串!!
class Question(models.Model):
question_text = models.CharField(max_length=200)
pub_date = models.DateTimeField('date published')
def __str__(self):
return self.question_text
需要重新启动 shell 才能生效。
$ python manage.py shell
Python 3.7.7 (default, Jul 16 2020, 18:28:35)
[Clang 10.0.1 (clang-1001.0.46.4)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> import django
>>> django.setup()
>>> from polls.models import *
>>> Question.objects.all()
<QuerySet [<Question: What's up>]> <------- テキストが見えた!
查询中可以使用 pk 这个字。
表中只有一个名为 id 的列,但是可以使用 pk 来表示 id=1 的意思。很方便!
>>> q = Question.objects.get(pk=1)
>>> q.was_published_recently()
True
在创建relations的记录时,没有.save()方法。
>>> q.choice_set.create(choice_text='Not much', votes=0)
这个操作一执行就会被提交。不知道有什么区别,也不知道”choice_set”这个词是从哪里来的,完全不明白。可能是在进行关联时的一个规则吧,肯定是。
编写你的第一个Django应用,第2部分
激活管理员
按照教程完成后,可以操作模型时能够看到记录的历史,真是太厉害了。
python manage.py createsuperuser
然后,您可以通过/login进入内部。
http://127.0.0.1:8000/login (请将此链接复制到浏览器地址栏中)
如何实现呢? → DB中有更改日志。
SELECT * FROM `django_admin_log`
可能只有通过管理员操作才会留下记录。用途不太明确。
通过 fieldsets 对 admin panel 进行可视化调整,在 column 中添加 HTML 的 header。
这里似乎不会被使用,所以跳过阅读似乎是个好主意…
编写你的第一个Django应用,第三部分¶
创建HTML视图。虽然不太需要作为API服务器,但为了基础知识还是做一下吧。
urlpatterns = [
url(r'^$', views.index, name='index'),
]
这个正则表达式不起作用,是怎么回事呢?当我想到是什么原因的时候,发现输入的内容完全不同。
不是用path(),而是用url()吗?
直接替换文件后就可以工作了。
我不想使用Jinja,但姑且先用它。Django会自动读取模板目录。
通过context将值传递给template.render()。
然后链接会自动添加。
啊,原来是在Jinja中使用对象来创建的。
原来如此。
实时渲染
这个和那个是一样的。
def index(request):
latest_question_list = Question.objects.order_by('-pub_date')[:5]
template = loader.get_template('polls/index.html')
context = {
'latest_question_list': latest_question_list,
}
return HttpResponse(template.render(context, request))
def 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)
这种相同的写法让人很难受。
404
当设置为404时
在/polls/13/处不存在。
是。
找不到页面(404)
在…之后, …zhī
问题并不存在
教我。
404快捷方式
这两个是一样的。
def detail(request, question_id):
try:
question = Question.objects.get(pk=question_id)
except Question.DoesNotExist:
raise Http404("Question does not exist")
return render(request, 'polls/detail.html', {'question': question})
def detail(request, question_id):
question = get_object_or_404(Question, pk=question_id)
return render(request, 'polls/detail.html', {'question': question})
错误信息是:没有问题与给定的查询相匹配。
成为了
view這樣應該可以
编写你的第一个Django应用程序,第四部分¶
由于是关于Jinja的话题,完全跳过。
编写你的第一个Django应用程序,第5部分
放置 polls/tests.py
运行命令`python manage.py test polls`的中文本地化版本:
可以进行测试。有趣的是,只需使用 Question(pub_date=time) 就可以创建一个临时的虚拟数据库记录。
视图的测试是什么?
从django.core.urlresolvers模块导入reverse函数。
因为这个被绊倒了,所以我决定跳过它。
编写你的第一个Django应用,第6部分
CSS追加的方式
创建 /polls/static/polls/styles.css.
{% 加载静态文件 %}
读取。
嗯,我略有了解 Django。