Django视图

5 篇文章 0 订阅

Django视图



1、认识试图

视图是Django框架的核心之一,它接收处理URLconfs分发的HTTP请求,返回响应。

视图的功能决定了它的基本结构,结构示意如下:

def view_name(request, *arg=None, **kwargs=None):
    代码段
    return HttpResponse(response)
#request必选参数,用于接收请求对象(HttpRequest类的实例)
#arg, kwargs为可选参数,用于接收URL中的额外参数
#返回值用于返回响应对象HttpResponse类或其子类的实例

实例1:

在views.py文件中定义一个返回当前日期和时间的视图curr_time(),具体代码如下:

from django.http import HttpResponse
import datetime
def curr_time(request):
    now = datetime.datetime.now()
    response = "<html><body>It is %s.</body></html>" % now
    return HttpResponse(response)

为了方便代码维护和防止视图臃肿,根据MTV模式,Django提倡将页面样式放在模板文件之中,在试图文件中使用上下文字典向模板传递数据。

实例2:

提取视图curr_time()中的样式代码,将其放在HTML文件time.html中。

<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
    <title>当前时间</title>
</head>
<body>
It is {{now}}.
</body>
</html>

以上变量now表示当前时间,它接收从视图函数中传来的数据。以下为view.py文件中视图函数代码:

from django.http import HttpResponse
from django.template import loader
import datetime
def curr_time(request):
    t = loader.get_template("time.html")      #加载模板
    now = datetime.datetime.now()       #获取当前时间
    context = {                         #上下文字典
        'now':now,
    }
    response = t.render(context, request)  #渲染模板
    return HttpResponse(response)

过程:视图函数curr_time()先使用django.template.loader模块的get_template()函数加载模板文件time.html,生成模板对象,然后获取当前时间,将当前时间存储到上下文字典中,之后使用模板对象的render()函数结合请求消息request和上下文字典渲染模板,最后返回响应对象。


2、请求对象

请求对象由Django自动创建,由视图的requests参数接收,Django项目中所有请求的处理都离不开请求对象。

请求对象是HttpRequest类的实例,其中封装了HTTP请求。通过HttpRequest类内定义的属性和方法可以访问与HTTP请求相关的信息。

  • HttpRequest的常用属性:
HttpRequest.body               #包含原始HTTP请求的请求体信息,属性为bytes

HttpRequest.path               #包含请求页面的完整路径,即文件的访问路径"/index.html/13",属性为字符串

HttpRequest.method             #包含本次请求所用的方法

HttpRequest.GET                #包含GET请求的所有参数,属性为QueryDict对象  HttpRequest.GET.get('name')取name参数的值

HttpRequest.POST   

HttpRequest.COOKIES           #包含所有Cookie信息,属性为一个字典数据,其中的键和值为字符串类型

HttpRequest.session          #包含当前会话信息,属性为QueryDict对象

HttpRequest.site             #包含由get_current_site()返回的Site或RequestSite实例,表示当前站点。

HttpRequest.user            #包含当前登录用户的相关信息,属性为一个User对象

HttpRequest.META            #包含HTTP请求的头部信息,该属性为dict类型
  • HttpRequest的常用方法:
HttpRequest.get_host()
HttpRequest.get_port()
HttpRequest.get_full_path()
HttpRequest.build_absolute_uri(location=None)   #返回location的绝对URI
HttpRequest.get_signed_cookie()
HttpRequest.is_ajax()        #判断当前请求是否由AJAX发送,若是则返回True

3、响应对象

a、HttpResponse类

最基础的响应类

  • HttpResponse的常用属性

    HttpResponse.content     #设置响应消息的内容,值为字节类型
    
    HttpResponse.charset     #设置响应消息的编码方式
    
    HttpResponse.status_code   #用于设置相应的状态码
    
    HttpResponse.reason_phrase   #用于设置相应的HTTP原因短语
    
  • HttpResponse的常用方法

    HttpResponse.__init__()
    
    HttpResponse.set_cookie()   #用于设置Cookie信息
    
    HttpResponse.set_signed_cookie()  
    
    HttpResponse.del_cookie()    #使用给定密钥删除Cookie
    
  • 使用HttpResponse类

    使用HttpResponse类创建响应对象的简单方式是传递一个字符串(这个字符串将作为页面的内容呈现)到HttpResponse类的构造函数。

    response1 = HttpResponse("Here's the text of the Web page.")
    response2 = HttpResponse("Text only, please.", content_type="text/plain")
    response3 = HttpResponse(b'Bytestrings are also accepted.')
    

    可用write()方法向其中追加内容:

    response = HttpResponse()
    response.write("<p>Here's the text of the web page</p>")
    response.write("<p>Here's another paragraph</p>")
    

    HttpResponse类的构造函数也可以接收一个可迭代对象,HttpResponse()接收到可迭代对象后,立刻以字符串形式存储可迭代对象中的内容,当数据存储完成后销毁可迭代对象(如接收一个文件对象,内容存储完毕后立刻调用close()方法关闭文件对象)

b、HttpResponse的子类
  • HttpResponseRedirect

    HttpResponseRedirect类接收的响应信息是URL。

    return HttpResponseRedirect("http://example.com")    #链接
    return HttpResponseRedirect("/search/")            #绝对路径
    return HttpResponseRedirect("search")              #相对路径
    

    注:该类只支持硬编码链接,不能直接使用URL名称,若要使用URL名称,需要先使用反向解析方法reverse()解析URL,例如使用命名空间blog下名为article_list()的URL,实例:

    return HttpResponseRedirect(reverse('blog:article_list'))
    
  • JsonResponse

    返回json类型的响应

    from django.http import JsonRespone
    def json_view(request):
        response = JsonResponse({'foo':'bar'}, safe=False)
        return response
    

    当调用json_view()视图时,页面会显示JSON数据“{‘foo’:‘bar’}”.

    将safe设置为False时,不止可转存dict类型数据,还可以转存非dict类型数据。比如下面:

    from django.http import JsonResponse
    def json_view(request):
        response = JsonResponse(['coding', 'fish'], safe=False)
        return response
    
c、其他HttpResponse的子类

异常响应处理:

HttpResponseNotModified         #304 页面在上次请求后未改变,无参数

HttpResponseBadRequest         #400 表示错误的请求

HttpResponseNotFound           #404 表示页面不存在

HttpResponseForbidden         #403 表示禁止访问

HttpResponseNotAllowed        #405 表示禁止访问

HttpResponseGone              #410

HttpResponseServerError       #500 表示服务器错误

实例:对商品实现增删改查

from django.shortcuts import loader
from django import http
from .models import Goods
from django.views.generic.base import TemplateView, RedirectView
from django.shortcuts import get_object_or_404,redirect,reverse
from django.forms import ModelChoiceField
from django.views import View
from django.shortcuts import render
#from django.views.decorators.csrf import csrf_exempt
'''
class GoodView(TemplateView):
    template_name = "goods.html"
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['goods'] = Goods.objects.all()
        return context
class DeleteGood(RedirectView):
    url = '/goods/'
    # pattern_name = 'goods:good'
    permanent = True
    #query_string = True
    def get_redirect_url(self, *args, **kwargs):
        good = get_object_or_404(Goods, id=kwargs['gid'])
        good.delete()
        # kwargs={}
        print(args)
        print(kwargs)
        return super().get_redirect_url(*args, **kwargs)

def get_goods(request):
    """展示商品"""
    t = loader.get_template('goods.html')  #加载模板
    goods = Goods.objects.all()    #获取数据
    context = {
        'goods':goods,          #构造上下文字典
    }
    response = t.render(context, request)  #结合上下文和请求对象生成响应信息
    return http.HttpResponse(response)

def del_good(request, gid):
    """删除指定商品"""
    good = Goods.objects.get(id=gid)  #获取待删除商品的id
    good.delete()          #删除该商品
    return http.HttpResponseRedirect('/goods/') #重定向到首页,展示新的商品列表
# Create your views here.
'''
class GoodView(View):
    '''商品视图类'''
    def get(self, request):
        '''展示商品'''
        goods = Goods.objects.all()
        context = {
            'goods':goods,
        }
        return render(request, 'goods.html', context)

    def post(self, request):
        """添加商品"""
        good = Goods()
        try:
            """参数不能少,少的话会出错"""
            good.name = request.POST.get('good_name')     #获取post传递的参数
            good.price = request.POST.get('good_price')
            good.stock = request.POST.get('good_stock')
            good.sales = request.POST.get('good_sales')
            good.save()
            #print("<h1>hello boy</h1>")
            # return redirect('/')  # 快捷方式
            return redirect(reverse('goods:info'))
        except Exception as e:
            return http.HttpResponseForbidden('数据错误')


class UpdateDestoryGood(View):
    '''编辑或删除商品'''
    def get(self, request, gid):
        '''删除商品数据'''
        try:
            good = Goods.objects.get(id=gid)
            good.delete()
        except Exception as e:
            return http.HttpResponseForbidden('删除失败')
        return redirect(reverse('goods:info'))   #反向解析

    def post(self, request, gid=0):
        '''编辑商品'''
        goods = Goods.objects.all()
        count = goods.count()
        try:
            num = request.POST.get('good_num')
            for i in range(1, count + 1):
                if i == int(num):   #找出要修改的那一行
                    good = goods[i - 1]   #将那一行的数据赋值给good
                    good.name = request.POST.get('good_name')
                    good.price = request.POST.get('good_price')
                    good.stock = request.POST.get('good_stock')
                    good.sales = request.POST.get('good_sales')
                    good.save()
                    break
        except Exception as e:
            return http.HttpResponseForbidden('编辑失败')
        return redirect(reverse('goods:info'))

效果:

do

容易出现的问题:
  • urls.py中路由匹配错误导致404

    解决:对照模板,分析路由匹配过程,不断调试

  • 数据无法插入数据库:

    解决:有可能是参数有缺失(加上就行),也有可能用户的输入与数据库字段类型不符(处理好报错,设置好数据库字段类型)。

    AttributeError: ‘str’ object has no attribute ‘tzinfo’

    参考文章:传送门

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值