草庐IT

django基础02--一个基于数据库的小项目

codingchen 2023-03-28 原文

摘要:简单修改、增加部分页面,了解django开发的过程。(Python 3.9.12,django 4.0.4

接前篇,通过命令: django-admin startproject myWebSite 创立了新的站点,cd myWebSite进入到站点根目录,并用命令python manage.py runserver 8080(或其他端口号) 就可使项目运行,然而这只是一个空壳,无任何作用,下面通过一个小应用对开发过程进行介绍。

退出运行状态:当项目运行时,按下键盘上的ctrl和Break键,退出到根目录下。

 一、创建一个显示当前日期和时间的网页

1、Django项目由一系列应用程序组成,比如,一个站点分别由不同的版块组成,每一个版块可以是一个独立的站点,它们协同工作,让项目成为一个整体

首先,创建一个应用程序,anaconda promt 中进入到根目录下,输入命令:python manage.py startapp myblogs 

这样,在根目录下,有4个文件,其中myblogs和myWebSite是2个文件夹,数据库db.sqlite3,以及manage.py文件。

进入到myWebSite文件夹中:

1)修改setting.py文件如下:

    'django.contrib.staticfiles',
    'myblogs',  #增加此行
]
# 中间略去 N 行
LANGUAGE_CODE = 'zh-hans'  #修改为中文,页面显示为中文
TIME_ZONE = 'Asia/Shanghai'  #修改时区

2)修改urls.py文件

urlpatterns = [
    path('admin/', admin.site.urls),#系统默认
path('myblogs/', include('myblogs.urls')),#在路径“myblogs/”中,找到myblogs.urls文件,并读取urls中的配置() ]

进入到myblogs文件夹中:

1)修改urls.py文件如下:(如果没有,把myWebSite文件夹中的拷贝过来修改)

from django.contrib import admin
from django.urls import path
from . import views       # 导入myblogs文件夹中的views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.current_datetime, name='datetime'),      #调用views.py文件中的current_datetime

2)修改views.py文件如下:

from django.shortcuts import render
from django.http import HttpResponse  # 从django.http 模块导入(import) HttpResponse 类
import datetime   #从Python标准库(自带)中导入datetime 模块

def current_datetime(request): #定义一个视图函数current_datetime 的函数current_datetime。
    now = datetime.datetime.now()  # datetime.datetime.now(),获取当前时间,并保存为局部变量 now 
    html = "<html><body>It is now %s.</body></html>" % now 
    #用 Python 的格式化字符串(format-string)功能构造一段 HTML 响应
    #字符串里面的 %s 是占位符,字符串之后的百分号表示使用变量 now 的值替换 %s
    
    return HttpResponse(html)  #视图返回一个包含所生成响应的 HttpResponse 对象

 保存上述相关文件,并运行 manage.py runserver 8090

在浏览器中输入  http://127.0.0.1:8090/myblogs/  即打开一个页面,并显示当前时间。

 二、创建应用

上述例子视图中返回文本,HTML被直接写入 Python 代码之中的,是不现实的,因为页面往往显示更多的内容,以及需要频繁地修改。这会导致下列问题:

1)每次对页面设计的进行的修改都必须对 Python 代码进行改动。
2)Python 代码编写和 HTML或css 设计是两项不同的工作,实际开发过程中,会分配给不同的人员(甚至不同部门)来完成。
3)开发人员编写 Python 代码和设计人员制作模板同时进行的工作方式效率是最高的。
基于上述原因,将页面的设计和Python的代码分离开会更干净简洁更容易维护,可以使用 Django的 模板系统 (TemplateSystem)来实现这种模式。

1、创建数据库

由于Django将大部分与项目相关的信息都存储在数据库中,因此需创建一个供Django使用的数据库。为给项目创建数据库,退出上述服务运行,并执行命令:python manage.py migrate

如上图完成后,位于myWebSite根目录下的db.sqlite3文件大小不为0,如下图:

2、创建应用模块

 由于之前已创立myblogs应用,现在创建相关模块。打开myblogs文件夹下的models.py文件,修改如下:

from django.db import models

class Topic(models.Model): #创建一个topic类,
    text = models.CharField(max_length=200)  #属性text是一个CharField,由字符或文本组成的数据
    date_added = models.DateTimeField(auto_now_add=True)
   
    def __str__(self):  #返回存储在属性 text中的字符串
        return self.text

要使用创建的模型,必须让Django将应用程序包含到项目中。为此,打开myWebSite文件夹下的settings.py文件,并进行如下配置:

INSTALLED_APPS = [
    'myblogs',
    'django.contrib.admin',
    'django.contrib.auth',
.
.
.

为使数据库能够存储与模型 Topic 相关的信息,需要对数据库进行更新,分别执行命令: python manage.py makemigrations myblogs 和 python manage.py migrate 运行结果如下:

 

 3、管理网站

有效地管理Web应用程序,网站管理员通常需要访问网站存储的所有信息

1)创建管理员帐户:直接输入命令:python manage.py createsuperuser 如下图

注意:输入密码时,无显示

 4、向网站注册模型

对于我们创建的模型,必须手工进行注册,创建应用程序myblogs时,Django在models.py所在的目录中创建了一个名为admin.py的文件,打开并做如下修改:

from django.contrib import admin
from myblogs.models import Topic   #导入需要注册的模型Topic

admin.site.register(Topic)  #使用 admin.site.register()注册,让Django通过管理网站管理模型

接下来运行服务,就可以访问超级用户账户并管理网站。运行命令:python manage.py runserver 8090,并打开  http://127.0.0.1:8090/admin

即可进行登录界面,输入用户名和密码,显示如下:

点击topics后的增加,添加java、python、c++等。

5、增加新模型,具体代码如下: 

from django.db import models

class Topic(models.Model): #创建一个topic类,
    text = models.CharField(max_length=200)  #属性text是一个CharField,由字符或文本组成的数据
    date_added = models.DateTimeField(auto_now_add=True)
   
    def __str__(self):  #返回存储在属性 text中的字符串
        return self.text
    
class Entry(models.Model):   # 新建一个模型
    topic = models.ForeignKey(Topic,on_delete=models.CASCADE) #属性topic是一个ForeignKey实例,topic创建时,都给它分配了一个键
    text = models.TextField() #属性text,它是一个TextField实例
    date_added = models.DateTimeField(auto_now_add=True)
    
    class Meta:  #在 Entry 类中嵌套了Meta类,用于管理额外信息
        verbose_name_plural = 'entries'
        
    def __str__(self):  #返回text中前50个字符,后面用省略号替代。
        return self.text[:50] + "..."

由于新加一个新模型,因此需要再次迁移数据库。
执行命令 python manage.py makemigrations myblogs
再执行命令 python manage.py migrate

继续注册,修改myWebSite\myblogs中admin.py文件,如下图:

from django.contrib import admin
from myblogs.models import *   #导入我们要注册的模型,注意由原来的 import Topic 修改为import * 了

admin.site.register(Topic)  #使用 admin.site.register()注册,让Django通过管理网站管理模型
admin.site.register(Entry)

 保存后,运行服务并登录管理员帐户,即可添加如下内容。

 三、创建网页:blogs主页

从上面的过程中可以看出,创建网页的过程通常分三个阶段:定义URL、编写视图和编写模板 

1)定义URL:URL模式描述了URL是如何设计的,让Django知道如何将浏览器请求与网站URL匹配,以确定返回对应的网页。每个URL都被映射到特定的视图——视图函数获取并处理网页所需的数据。

2)视图:视图函数通常调用一个模板,后者生成浏览器能够理解的网页。

3)模型:数据库驱动的 Web 应用的第一步是定义模型 - 也就是数据库结构设计和附加的其它元数据。模型是真实数据的简单明确的描述。它包含了储存的数据所必要的字段和行为。

1、修改urls文件

打开项目主文件夹myWebSite中的文件urls.py文件,并进行如下修改:

from django.contrib import admin   
from django.urls import path,include
#导入为项目和管理网站管理URL的函数和模块

urlpatterns = [
    path('admin/', admin.site.urls),
    path('myblogs/', include('myblogs.urls')),
    #包含模块myblogs.urls,包含实参name,可将myblogs的URL同项目中的其他URL区分开来
]

打开项目主文件夹myblogs中的文件urls.py文件(如果没有,可把上述文件拷贝后修改),并进行如下修改:

from django.contrib import admin
from django.urls import path
from . import views      

app_name='myblogs'
urlpatterns
= [ path('admin/', admin.site.urls), path('', views.index, name='index'), ]

2、编写视图

视图函数 接受请求中的信息,准备好生成网页所需数据,再将这些数据发送给浏览器。打开myblogs中的views.py文件,修改如下并保存:

from django.shortcuts import render
from django.http import HttpResponse  
import datetime   

"""
def current_datetime(request): #定义一个视图函数current_datetime 的函数current_datetime。
    now = datetime.datetime.now()  # datetime.datetime.now(),获取当前时间,并保存为局部变量 now 
    html = "<html><body>It is now %s.</body></html>" % now 
    #用 Python 的格式化字符串(format-string)功能构造一段 HTML 响应
    #字符串里面的 %s 是占位符,字符串之后的百分号表示使用变量 now 的值替换 %s
    
    return HttpResponse(html)  #视图返回一个包含所生成响应的 HttpResponse 对象
"""
def index(request):
    return render(request, 'myblogs/index.html')

暂时隐藏部分内容。

3、创建一个index.html文件,代码如下:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html lang="en">
<head>
<title>Future time</title>
</head>
<body>
<h1>welcome to my site!</h1>
<p></p>
<hr>
<p>Thanks for visiting my site.</p>
</body>
</html>

(不了解html语言可以先了解一下,这里不做过多介绍。)  在文件夹myblogs中新建一个文件夹,并将其命名为templates。在文件夹templates中,再新建一个文件夹,并将其命名为myblogs,即:myWebSite\myblogs\templates\myblogs

并将index.html文件保存到此目录下。

保存并运行命令:python manage.py runserver 8090  。在浏览器中输入:http://127.0.0.1:8090/myblogs/ 即可看到如下画面:

四、扩充更多的网页

1、模板继承

创建网站时,几乎都有一些所有网页都将包含的元素。比如上面显示的“welcome to my site“,让它显示在所有相关的网页上,因此可编写一个包含通用元素的父模板,并让其他的网页都继承这个模板即可。

1)创建一个简单的父模板base.html

在文件目录myWebSite\myblogs\templates\myblogs下,新建一个base.html文件,内容如下:

<p>     
<a href="{% url 'myblogs:index' %}">welcome to my blogs site!</a>
</p>
{% block content %}   #插入了一对块标签。这个块名为 content ,是一个占位符,其中包含的信息将由子模板指定

2) 修改index.html文件,让其继承base.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
{% extends "myblogs/base.html" %}

{% block content %}
<p>Thanks for visiting my site!</p>
{% endblock content %}

运行结果:

2,简单的链接的页面

1)在myWebSite\myblogs\templates\myblogs下,增加一个topics.html文件

{% extends "myblogs/base.html" %}
{% block content %}
<ul>
{% for topic in topics %}
<li>{{ topic }}</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}

2)修改myblogs文件中的urls.py文件

from django.contrib import admin
from django.urls import path
from . import views  

app_name='myblogs'
urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index, name='index'),
    path('topics/',views.topics,name='topics'),
]

3)修改主站点的urls文件(myWebSite文件夹)

from django.contrib import admin  
from django.urls import path, include  

urlpatterns = [  
    path('admin/', admin.site.urls),
    path('myblogs/',include('myblogs.urls')),  
    path('topics/',include('myblogs.urls')), 
]

4)修改myblogs文件中的views文件

from django.shortcuts import render
from django.http import HttpResponse  
from .models import *

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

def topics(request):
    topics = Topic.objects.order_by('date_added') #查询数据库——请求提供 Topic 对象
    context = {'topics':topics}
    return render(request,'myblogs/topics.html',context) 

保存并运行。打开 :http://127.0.0.1:8090/myblogs/ 点击Blogs如下所示:

 

点击Topics如下所示:

一个简单可交互的网站就诞生了。

3、显示特定主题的页面

前面增加了python、java、c++描述,如何在不同的页面显示。

1)增加新的视图

由于在新的页面中,显示模型类Entry的text属性,因此需要新增加视图,如下:

from django.shortcuts import render
from django.http import HttpResponse  
from .models import *

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

def topics(request):
    topics = Topic.objects.order_by('date_added') #查询数据库——请求提供 Topic 对象
    context = {'topics':topics}
    return render(request,'myblogs/topics.html',context) #将变量 context 传递给 render() 

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, 'myblogs/topic.html', context)

2)修改myblogs文件中的urls.py文件

from django.contrib import admin
from django.urls import path
from . import views  

app_name='myblogs'

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.index, name='index'),
    path('topics/',views.topics,name='topics'),
    path('topics/(?P<topic_id>\d+)/', views.topic, name='topic'),
]

3)修改html文件:

修改topics文件,如下:

{% extends "myblogs/base.html" %}
{% block content %}
<p>Topics</p>
<ul>
{% for topic in topics %}
<li>
<a href="{% url 'myblogs:topic' topic.id %}">{{ topic }}</a>
</li>
{% empty %}
<li>No topics have been added yet.</li>
{% endfor %}
</ul>
{% endblock content %}

新增加一个topic.html文件:

{% extends "myblogs/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>
There are no entries for this topic yet.
</li>
{% endfor %}
</ul>
{% endblock content %}

保存后运行,打开浏览页面如下:

 

 

有关django基础02--一个基于数据库的小项目的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  4. ruby-on-rails - 渲染另一个 Controller 的 View - 2

    我想要做的是有2个不同的Controller,client和test_client。客户端Controller已经构建,我想创建一个test_clientController,我可以使用它来玩弄客户端的UI并根据需要进行调整。我主要是想绕过我在客户端中内置的验证及其对加载数据的管理Controller的依赖。所以我希望test_clientController加载示例数据集,然后呈现客户端Controller的索引View,以便我可以调整客户端UI。就是这样。我在test_clients索引方法中试过这个:classTestClientdefindexrender:template=>

  5. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

  6. ruby - 为什么 SecureRandom.uuid 创建一个唯一的字符串? - 2

    关闭。这个问题需要detailsorclarity.它目前不接受答案。想改进这个问题吗?通过editingthispost添加细节并澄清问题.关闭8年前。Improvethisquestion为什么SecureRandom.uuid创建一个唯一的字符串?SecureRandom.uuid#=>"35cb4e30-54e1-49f9-b5ce-4134799eb2c0"SecureRandom.uuid方法创建的字符串从不重复?

  7. ruby-on-rails - Rails - 从另一个模型中创建一个模型的实例 - 2

    我有一个正在构建的应用程序,我需要一个模型来创建另一个模型的实例。我希望每辆车都有4个轮胎。汽车模型classCar轮胎模型classTire但是,在make_tires内部有一个错误,如果我为Tire尝试它,则没有用于创建或新建的activerecord方法。当我检查轮胎时,它没有这些方法。我该如何补救?错误是这样的:未定义的方法'create'forActiveRecord::AttributeMethods::Serialization::Tire::Module我测试了两个环境:测试和开发,它们都因相同的错误而失败。 最佳答案

  8. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  9. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  10. ruby - 一个 YAML 对象可以引用另一个吗? - 2

    我想让一个yaml对象引用另一个,如下所示:intro:"Hello,dearuser."registration:$introThanksforregistering!new_message:$introYouhaveanewmessage!上面的语法只是它如何工作的一个例子(这也是它在thiscpanmodule中的工作方式。)我正在使用标准的ruby​​yaml解析器。这可能吗? 最佳答案 一些yaml对象确实引用了其他对象:irb>require'yaml'#=>trueirb>str="hello"#=>"hello"ir

随机推荐