4. 读取数据库数据 前后端分离架构

操作系统:windows
IDE:Pycharm

读取数据库数据:

现在已经有了数据库和定义好的Customer表,也在表中添加了两条数据信息。
现在需要实现一个功能:前端浏览器访问 sales/customers/这个URL,后端服务端就返回用户的记录给浏览器。

首先需要实现一个函数,来处理浏览器发出的URL为 sales/customers/ 的访问请求,我们需要返回数据库中customer表中的所有记录。

Django 中对数据库表的操作, 应该都通过 Model对象 实现对数据的读写,而不是通过SQL语句。

需要获取customer表所有记录, 该表是由之前定义的 Customer类进行操作的。

获取所有的表记录:

在文件sales/views.py 中,定义一个listcustomers函数,内容如下:

# 导入 Customer 对象定义
from  common.models import  Customer

# 列出客户信息
def listcustomers(request):
    # values()方法返回一个QuerySet对象,包含所有的表记录
    # 每条表记录都是是一个dict对象,
    # key是字段名,value是字段值
    # objects是Customer的父类Model用来操作数据库的Manage接口,由Django定义
    qs = Customer.objects.values()

    # 定义返回字符串
    retStr = ''
    for customer in qs:
        for name, value in customer.items():
            retStr += f'{name} : {value} | '

        # <br> 表示换行
        retStr += '<br>'

    return HttpResponse(retStr)

QuerySet 对象 可以使用 for 循环遍历取出里面所有的元素,每个元素对应一条表记录。每条表记录元素都是一个dict对象,其中 每个元素的key是表字段名,value是该记录的字段值。

然后还要在 sales/urls 二级路由表中添加上对应的路由信息:

from django.urls import path
from sales.views import listorders, listcustomers

urlpatterns = [

    path('orders/', listorders),
    path('customers/', listcustomers)


]

运行之后,用浏览器访问127.0.0.1:8080/sales/customers可以看到效果:
在这里插入图片描述
可以看到字符串作为html被浏览器解析,<br>实现了换行。简单实现了数据库中的信息被放到前端。


添加过滤条件:

有的时候,我们需要根据过滤条件查询部分客户信息。

比如,当用户在浏览器输入 /sales/customers/?phonenumber=150646442864,要求返回电话号码为 150646442864 客户记录。

我们可以通过filter方法加入过滤条件,修改view里面的代码,如下所示:

# 列出客户信息
def listcustomers(request):
    # values()方法返回一个QuerySet对象,包含所有的表记录
    # 每条表记录都是是一个dict对象,
    # key是字段名,value是字段值
    # objects是Customer的父类Model用来操作数据库的Manage接口,由Django定义
    qs = Customer.objects.values()

    # 检查url中是否有phonenumber
    # 从request对象的GET请求中,找key值:phonenumber, 如果没有就是None,操作有点像字典dict
    ph = request.GET.get('phonenumber', None)

    if ph:
        qs = qs.filter(phonenumber=ph)

    # 定义返回字符串
    retStr = ''
    for customer in qs:
        for name, value in customer.items():
            retStr += f'{name} : {value} | '

        # <br> 表示换行
        retStr += '<br>'

    return HttpResponse(retStr)

Django框架在url路由匹配到函数后, 调用函数时,会传入一个HttpRequest对象给参数变量 request,该对象里面包含了请求的数据信息。

HTTP 的 Get 请求url里面的参数(术语叫 querystring 里面的参数),可以通过 HttpRequest对象的 GET 属性获取。这是一个类似dict的对象。

例如一个url:/users/?id=123&tel=15050 ,执行到request.GET时,会把所有参数取出来放到一个字典当中:

request.GET = {
	'id':'123',
	'tel':'15050'
}

然后通过调用 QuerySet 对象的filter方法,就可以把查询过滤条件加上去

qs = qs.filter(phonenumber=ph)

有了这个过滤条件,Django会在底层执行数据库查询的SQL语句加上相应的 where从句,进行过滤查询。

注:

  1. 参数名 phonenumber 是和定义的表 model的属性名 phonenumber 一致的。
  2. filter的过滤条件可以有多个,只要继续在后面的参数添加过滤条件即可。

打开浏览器,访问127.0.0.1:8080/sales/customers/?phonenumber=150646442864
在这里插入图片描述
可以看到过滤条件生效了


使用模板来生成HTML:

上面的相当于简单的把数据放在网页上,如果要用一个表格来显示数据,该怎么做呢?
HTML其实也是一个字符串,可以用循环加上标签,拼接字符串来生成HTML,但这显然不是一个好方法。

很多后端框架都提供了一种模板技术, 可以在HTML中嵌入编程语言代码片段, 用模板引擎(就是一个专门处理HTML模板的库)来动态的生成HTML代码。
比如JavaEE 里面的JSP
Python 中有很多这样的模板引擎 比如 jinja2Mako, Django也内置了一个这样的模板引擎。

现在使用Django的模板引擎,来构建出 HTML 字符串内容:
还是在sales/views.py中:

# 先定义好HTML模板
html_template = '''
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
table {
    border-collapse: collapse;
}
th, td {
    padding: 8px;
    text-align: left;
    border-bottom: 1px solid #ddd;
}
</style>
</head>
    <body>
        <table>
        <tr>
        <th>id</th>
        <th>姓名</th>
        <th>电话号码</th>
        <th>地址</th>
        </tr>

        <!-- customers就是从数据库中读出来的QuerySet对象 -->        
        {% for customer in customers %}
            <tr>

            {% for name, value in customer.items %}            
                <td>{{ value }}</td>            
            {% endfor %}

            </tr>
        {% endfor %}

        </table>
    </body>
</html>
'''

# engines就是Django自带的的模板引擎
# template这里就是模板对象
from django.template import engines
django_engine = engines['django']
template = django_engine.from_string(html_template)

def listcustomers(request):
    # 返回一个 QuerySet 对象 ,包含所有的表记录
    qs = Customer.objects.values()

    # 检查url中是否有参数phonenumber
    ph =  request.GET.get('phonenumber',None)

    # 如果有,添加过滤条件
    if ph:
        qs = qs.filter(phonenumber=ph)

    # 传入渲染模板需要的参数,把qs传入模板中的customers
    rendered = template.render({'customers': qs})

    return HttpResponse(rendered)

模板的效果如图,如果用模板实现更好的效果可以考虑了解一下bootstrap
在这里插入图片描述


前后端分离架构:

有了模板引擎,对我们后端开发来说,简化了程序员后端生成HTML的任务,提高了开发效率。但是实际生产过程中,基本都是前后端分离的架构。

不使用前后端分离,有什么弊端?

  1. 前后端开发人员要做额外的沟通。
  2. 如果前端除了web浏览器,还有手机APP的话, APP 不需要服务端返回HTML, 就得再开发一套数据接口
  3. 渲染任务在后端执行,大大的增加了后端的性能压力(render很吃CPU)。尤其是有的HTML页面很大, 当有大量的用户并发访问的时候, 后端渲染工作量很大,很耗费CPU 资源。

现在随着浏览器中javascript 解释器性能的突飞猛进,以及一些前端模板库和框架的流行。很多架构师将页面的html内容生成 的任务放到前端。

这样服务端就只负责提供数据, 界面的构成全部在前端(浏览器前端或者手机前端)进行,称之为前端渲染。这个工作在前端执行, 使用前端的框架库去完成,比如 AngularReactVue

这样界面完全交给前端开发人员去做, 后端开发只需要提供前端界面所需要的数据就行了。

前端和后端之间的交互就完全是业务数据了。

这样需要定义好前端和后端交互数据的接口

目前通常这样的接口设计最普遍的就是使用 REST 风格的 API 接口

  • 前端通过API 接口从后端获取数据展示在界面上。
  • 前端通过API 接口告诉后端需要更新的数据是什么。

通常前后端的 API 接口是由架构师设计的, 有时也可以由经验丰富的前端开发者、或者后端开发者设计。后端开发人员只需要根据这个接口文档,实现后端系统的部分。

注意:需要Django返回的信息,通常都是所谓的动态数据信息。 比如:用户信息,订单信息,等等这些信息通常都是存在数据库中,这些信息是会随着系统的使用发生变化的。

静态信息,比如: 页面HTML文档、css文档、图片、视频等,是不应该由 Django 负责返回数据的。

这些数据通常都是由其他静态资源服务软件,比如 NginxVarnish等等,返回给前端。这些软件都会有效的对静态数据进行缓存,大大提高服务效率。在实际的项目中,往往还会直接使用静态文件云服务( OSS + CDN )提供静态数据的访问服务。

总之,Django处理并返回的应该是动态业务数据信息。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
前后分离是一种开发架构模式,其中前和后的开发是分开进行的,通过API进行通信。而Node.js是一种基于JavaScript的运行环境,适用于构建高性能的网络应用程序。 在一个前后分离的电影网站中,前负责展示界面和用户交互,后则负责处理业务逻辑和数据的存储。 首先,前可以使用HTML、CSS和JavaScript来创建用户界面。通过Node.js框架如Express.js可以设置路由,响应用户的请求。前可以请求后提供的接口来获取电影数据或者提交用户的操作。 后主要负责处理数据和业务逻辑。使用Node.js,可以通过运行JavaScript的能力处理请求和响应。后可以与数据库交互来获取电影数据,并使用Node.js的文件系统模块来存储和读取相关文件。 在前后分离架构中,前将通过Ajax或Fetch等方法发送请求到后接口,后接收请求后会根据请求的参数和路径进行相应的处理,并返回数据给前,前再将数据展示到界面上。 这种架构使得前后的开发分离,可以提高开发效率和代码的可维护性。前可以专注于用户界面和交互,而后则可以专注于数据处理和业务逻辑。同时,前后可以并行开发,提高了开发的效率。 总结一下,Node.js适用于前后分离的电影网站的开发,它可以作为后的运行环境,并通过处理请求和响应来实现前后的交互。这种架构模式让前后的开发更加高效和可维护,提升了整体开发的效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值