给学习的过程做一个简单的记录
主要记录使用到的语句,过程中遇到的问题
python -m venv ll_env
上述语句创建虚拟环境, 其中的ll_env为虚拟环境的名称
激活虚拟环境:
source ll_env/bin/activate
ll_env\Scripts\activate
前者为Linux系统下语句,后者为Windows系统下语句
安装django:
pip install django
新建一个项目:
djando-admin.py startproject pro_name .
在项目的名字末尾最好加上一个句点
执行项目:
python manage.py runserver
新建一个应用程序:
python manage.py startapp app_name
在django中创建超级用户:
python manage.py createsuperuser
设置后需要设置root用户名以及密码
每次添加一个新模型后,需要再次迁移数据库:
python manage.py makemigrations learning_logs
python manage.py migrate
from django.db import models
# Create your models here.
class Topic(models.Model):
text = models.CharField(max_length=200)
date_add = models.DateTimeField(auto_now_add=True)
#添加一个返回值,不包含在返回值中的变量将不会被返回
def __str__(self):
return (self.text+' '+str(self.date_add))
class Entry(models.Model):
topic = models.ForeignKey(Topic, on_delete=models.CASCADE)
text = models.TextField()
data_added = models.DateTimeField(auto_now_add=True)
#给模型换一个名字,如果不添加下面这一条,会在entry后面直接加上s
class Meta:
verbose_name_plural = 'entries' #此处前面的变量名称是不可更改的
def __str__(self):
if len(self.text) > 50:
return self.text[:50]+'...'
else:
return self.text
添加模型后我们还需要再admin.py中注册模型
from learning_logs.models import Topic,Entry
admin.site.register(Topic)
admin.site.register(Entry)
如果我们想通过终端直接查看网页上面的数据,而不是点击页面。可以尝试通过django shell查看数据
首先
使用如下语句进入shell
python manage.py shell
接着导入你想查看的模块,比如说Topic
from learning_logs.models import Topic
用topics来获取topic中所有实例,返回值是一个列表,称为查询集
topics = Topic.objects.all()
也可以自行试试topic和topic.objects命令,会出现不同的结果
topics中每个对象都分配一个唯一的属性id,可以查看(属性 id 是从 1 开始计数)
print(topic.id)
而根据每个对象的id,我们可以查看其任何属性
t = Topic.objects.get(id=1)
t.text
t.date_add
上述变量中 t 被赋予了模块 Topic 中 id=1 的对象的所有属性,模型Entry中定义了一个与Topic关联的ForeignKey属性topic。
如果想查看与Topic相关联的条目,比如说Entry,可以通过相关模型的小写名称、下划线、和单词 set 来通过外键获取数据。
t = entry_set.all()
关于外键的访问,这篇博客提供了更加详细的说明
-----》django中如何添加、访问外键
使用django创建网页通常分三个阶段:定义URL、编写视图和编写模板。
每个URL都会被映射到特定的视图
简单的正则规则
^ 字符串开头
$ 字符串结尾
\d 数字
\s 任意的空白符
\w 字母数字下划线
{n} 重复n次
{n,m} 重复n到m次
. 匹配除换行符以外的任意字符
* 重复0次或多次
? 重复0次或1次
+ 重复1次或更多次
下面附上以下代码
learning_log.urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from learning_logs import views
app_name = 'learning_logs'
urlpatterns = [
path('admin/', admin.site.urls),
path('',include('learning_logs.urls','learning_logs'),
namespace='learning_logs'),
]
learning_logs.urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from . import views
urlpatterns = [
path('^$',views.index,name='index'),
]
learning_logs.views.py
from django.shortcuts import render
# Create your views here.
def index(request):
"""学习笔记的主页"""
return render(request,'learning_logs/index.html')
运行后显示以下问题
ImproperlyConfigured: Specifying a namespace in include() without providing an app_name is not supported. Set the app_name attribute in the included module, or pass a 2-tuple containing the list of patterns and app_name instead.
比对这篇博客django2.0中name和namespace的用法
试着把project中namespace参数放到include里面
path('',include('learning_logs.urls','learning_logs'))
仍然报告相同的错误
又尝试在app_urls中添加
app_name = 'learning_logs'
突然成功!看来问题出在刚才没有向apps里面添加 app_name
这里是一个详细解释----->django url 中的namespace详解
但是有一个warning要去解决:
WARNINGS:
?: (2_0.W001) Your URL pattern '^ $ ’ [name=‘index’] has a route that contains ‘(?P<’, begins with a ‘^’, or ends with a ‘$’. This was likely an oversight when migrating to django.urls.path().
又在网上找到一个解决方法-----》django3.1的url配置
因为前几年小蟒蛇上django版本采用1.11,但是现在django已经到了3.1版本,有的方法已经出现变化
如果直接照搬书上的源码会出现问题,不少地方需要直接查看帮助文档或者是往博客里面寻找解决方法
具体原因:
- 从Django2.0以后,urls.py配置不同
解决方案:
- 把url函数换成path
- 不适用^,$作路由
那么我们试着把app中urls.py改为
from django.contrib import admin
from django.urls import path
from django.conf.urls import include
from . import views
app_name = 'learning_logs'
urlpatterns = [
path('',views.index,name='index'),
]
这次就成功了
当前网址为http://127.0.0.1:8000/
试着修改一下网址
将http://127.0.0.1:8000/改为http://127.0.0.1:8000/index/
发现只要将project中urls改为
path(‘index/’,include(‘learning_logs.urls’,‘learning_logs’))
网址修改成功
在app中urls似乎不影响网址名称
我们带着疑问继续向下探寻
特别要注意的地方
当我们创建html文件,要将这个文件放在templates\app_name\路径下,文件名字稍有改动就会导致程序找不到html文件
-
模板继承
如果几乎所有的网页都包含有一部分相同的元素,可以通过模板继承来减少工作量 -
父模板
在简单的html页面中,锚标签是这样定义的:
<a herf="link_url">link text</a>
base.html
<p>
<a href="{% url 'learning_logs:index' %}">Learning Log</a>
</p>
{% block centent %}{% endblock content %}
模板文件中每个层级只缩进两个空格,因为模板文件的层级更多
当子文件中内容与父文件不同时,使用block来预先给子文件中不同部分预留位置
{% block 名称 %}
预留给子模板的区域
{% endblock 名称 %}
- 子模版
在子模版中通过extends来继承父模板的内容
{% extends “父模板路径”%}
重新编写index html使其继承base html
{% extends "learning_logs/base.html" %}
{% block centent %}
<p>Learning Log</p>
<p>Learning Log help you kepp track of your learning, for any topic you're
learning about.</p>
{% endblock centent %}
子模版第一行的extend让django知道继承的哪个父模板文件base.html位于文件夹learning_logs中,因此父模板路径中包含learning_logs。这行代码导入模板base.html的所有内容
-
显示所有主题的网页
- url 模式
path('topics/',views.topics,name='topics')
在应用中的urlpatterns添加上述url路径
按照料想,现在应该创建出三个url路径,分别是admin,index和topics但是在输入index/topics后却显示找不到该网页
为什么会这样?
一番调查后发现是我自己运行错了项目,错误地把另一个项目的运行结果当作是这个项目的运行结果。。。- views
def topics(request): """ 显示所有主题的页面""" topics = Topic.objects.all() context = {'topics':topics} return render(request,'learning_logs/topics.html',context)
在views中,context变量键值对代表的意义分别是html变量和views变量
{“HTML变量名” : “views变量名”}字典context通过render函数传递给html文件,从而使我们在html文件中也能使用字典里的变量
- 模板
{% extends "learning_logs/base.html" %} {% block content %} <p>Topics</p> <ul> {% for topic in topics %} <li>{{ topic }}</li> {% empty %} <li>No topics bro<li> {% endfor %} </ul> {% endblock content %}
在模板中,双括号括起来的部分是变量,如 {{topic}}
不能直接输出整个字典,
如果字典中键值对的值为列表,可以输出整个列表,或者用 . 取出列表中对应元素
变量部分还可以通过过滤器进行修改------>django-菜鸟教程
其中{% %}让html知道这是一段代码
{% if %}语句结束后需要带上{% endif %}语句
可选的 {% empty %} 从句:在循环为空的时候执行
注释使用 {# #}。views.py
def hello(request): context = {} context['hello'] = 'hello world!' context['intro'] = '大家好,我叫Patrick' context['info'] = ['my name','my age','my gender'] return render(request,'hello/hello.html',context)
hello.html
<h1>{{hello}}</h1> <p>This is my first day to use the django</p> <p>{{intro}}</p> <p>##{{info}}##<br> {{info.1}}</p>
- 显示特定主题的页面
- url模式
re_path(r'topics/(?P<topic_id>\d+)/',views.topic,name='topic')
- views
def topic(request,topic_id): topic = Topic.objects.get(id=topic_id) entries = topic.entry_set.order_by('-date_added') context = { 'topic':topic, 'entry':entries } return render(request,'learning_logs/topic.html',context)
- 模板
{% block content %} <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> There are no enteies for this topic right now </li> {% endfor %} </ul> {% endblock content %}
但是添加上的topic没有链接指向entry,并且直接通过链接访问entry一直显示无法解析关键字 ‘date_added’ 添加到字段中
解决办法戳这里------->FieldError:无法解析关键字“date_added”添加到字段中。选项包括:添加的数据、id、文本、主题、主题
然而访问后显示entry中没有数据
检查后破案了,topics页面之所以没有链接,是我把 a href 错打成 a herf ,但编译器没有报错,刚才也一直没有发现。
后来,我总算明白了错在哪里
date_added 打成 data_added
但是修改后问题仍未解决
上网参考别人的代码
此处应该为entries,修改后正常运行
后面把代码贴上来,遇到问题在想解决办法
django3.1的不同之处------->自学Python编程从入门到实践Django项目三18章19章的各种坑
看了这篇文章能少走不少弯路