最近在看Python编程:从入门到实践,这是这本书“项目3 Web应用程序”第18章的笔记。记录了django最基本的一些日常用法,以便自己查阅。

可能是我的这本书版本比较老,书上项目的代码直接跑跑不通,也有一些小小的错误。这里我做了一些修改。

基本用法

django-admin startproject 项目名 .python manage.py migratepython manage.py runserverpython manage.py startapp 应用程序名

激活模型:

python manage.py makemigrations 应用程序名

上述操作产生一个迁移文件(“0001_initial.py”),让Django应用这种迁移修改数据库:

python manage.py migrate

只要添加了新的模型,就需要重复上面两个命令再次迁移数据库。

python manage.py createsuperuserfrom xxx.models import 模型名admin.site.register(模型名)

然后就能使用超级用户账户访问管理网站了:http://localhost:8000/admin/

利用shell查看输入的数据

python manage.py shellfrom learning_logs.models import TopicTopic.objects.all()topics = Topic.objects.all()for topic in topics: 					print(topic.id, topic)t = Topic.objects.get(id=1)t.textt.date_added	t.entry_set.all()

其中entry是相关模型的小写名称,可以返回出与t相关的Entry的所有对象条目

创建一个主页

​ 分为三个阶段:定义URL、编写视图和编写模板
​ 每个URL对应特定的视图,视图调用一个模板,浏览器通过模板生成网页.

定义URL

在urls.py中的urlpatterns中添加相应的url。

书上的代码是:

在learning_log/urls.py中加入:
		url(r'', include('learning_logs.urls', namespace='learning_logs'))
目的是让learning_logs的URL同项目中的其他URL区分开。

然后在learning_logs中创建另一个urls.py文件,引入views
		from . import views
其中的urlpatterns中加入
		url(r'^$', views.index, name='index')

我的django版本与书上不同,没有url(),只有path()。

我的代码是:

在learning_log/urls.py中
path('', include('learning_logs.urls')),


在learning_logs/urls.py中
path('', views.index, name='index'),

------------------
并且要在此文件中声明:
app_name = 'learning_logs'
#不加会报:learning_logs is not a registered namespace

编写视图

views.py中,render()作用是根据提供的数据渲染响应。

书上为主页编写了视图

def index(request):
    return render(request, 'learning_logs/index.html')

编写模板

在learning_logs中新建一个文件夹,并将其命名为templates。在文件夹templates中,再新建一个文件夹,命名为learning_logs。这是Django能明确解读的结构。

在最里面的文件夹learning_logs中,建立index.html

书上的代码是:

<p>Learning Log</p>

<p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>

创建其他网页

这个部分书上的代码都跑不通,就把自己修改后的代码写上来。

父模板

base.html
<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a>
    <a href="{% url 'learning_logs:topics' %}">Topics</a>
</p>

{% block content %}{% endblock content %}

子模板

index.htmlbase.html
{% extends "learning_logs/base.html" %}

{% block content %}
  <p>Learning Log helps you keep track of your learning, for any topic you're learning about.</p>
{% endblock content %}

其中,不是从父模板继承的内容都包含在content块中

显示所有主题(Topics)的页面

定义所有主题页面的URL

修改learning_logs/urls.py,urlpatterns中加上:

path('topics/', views.topics, name='topics'),

视图

修改views.py,加上这段代码

def topics(request):
    _topics = Topic.objects.order_by('date_added')
    context = {'topics': _topics}
    return render(request, './learning_logs/topics.html', context)

context是要发给模板的上下文,是一个字典,键是在模板中要访问数据的名称,值是要发送给模板的数据。

模板

topics.html
{% extends "learning_logs/base.html" %}

{% block content %}

  <p>Topics</p>

  <ul>
      {% for topic in topics %}
        <li>{{topic}}</li>
      {% empty %}
        <li>No topics have been added yet.</li>
      {% endfor %}
  </ul>

{% endblock content %}

修改父模板,使其包含到所有这些页面的链接,改成这样

<p>
    <a href="{% url 'learning_logs:index' %}">Learning Log</a> -
    <a href="{% url 'learning_logs:topics' %}">Topics</a>
</p>

{% block content %}{% endblock content %}

显示特定主题(Topic)的页面

与上面的做法都类似:URL/视图/模板。

URL

在learning_logs/urls.py中,加入

path('topics/', views.topic, name='topic')

视图

views.py中,加入

def topic(request, topic_id):
    _topic = Topic.objects.get(id=topic_id)
    entries = _topic.entry_set.order_by('-date_added')
    context = {'topic': _topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

date_added前面的减号指定按降序排列。即先显示最近的条目,把主题和条目存进context中,再发送给topic.html

模板

新建topic.html

{% extends "learning_logs/base.html" %}

{% 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>No entry for this topic yet.</li>
    {% endfor %}
</ul>

{% endblock content %}

“|”表示模板过滤器,即这个后面是对模板变量修改的函数。

这里date中,M是month,d是day.........于是显示出来的就是这样:Jul 25, 2022 08:15

linebreaks将包含换行符的长条目转换为浏览器能够理解的格式,以免显示为一个不间断的文本块。

将这些topic的页面设置为链接

topics.html
{% extends "learning_logs/base.html" %}

{% block content %}

<p>Topics</p>

<ul>
    {% for topic in topics %}
    <li>
        <a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a>
    </li>
    {% endfor %}
</ul>

{% endblock content %}

贴几张到此为止的网页截图: