Django的get_absolute_url方法的使用

目录
  • 一、创建模型
  • 二、设计urls
  • 三、编写视图
  • 四、HTML模板
  • 五、使用get_absolute_url方法
  • 六、总结思考

本文主要的目的是通过一个简单的例子,展示`get_absolute_url`的用法,抛砖引玉,理解实例方法的本质,能够在不同的业务场景下,灵活多变,完成需求。

环境:Python3.8 + Django3.0

我们都知道,在反向解析url的时候,Django提供了三种方法,帮我们替代硬编码的方式,也就是:

  • 在模板中:使用url模板标签。
  • 在Python代码中:使用reverse()函数。
  • 在更高层的与处理Django模型实例相关的代码中:使用get_absolute_url方法。

前面两种方式比较常见,我们也很熟悉,但是最后的get_absolute_url方法,可能很多人就不明白具体如何使用了。下面我们通过一个简单易懂的例子,来搞懂它的具体使用方法。

一、创建模型

首先,假设我们有下面的学生模型:

class Student(models.Model):

    sex_choice = [
        ('man', '男性'),
        ('woman', '女性'),
    ]

    name = models.CharField(max_length=128)
    sex = models.CharField(max_length=8, choices=sex_choice)
    tel = models.PositiveIntegerField()

    def __str__(self):
        return self.name

学生包含姓名、性别和电话。

不要忘记makemigrations和migrate。

然后我们接入admin后台,随意手动创建一些学生实例:

from django.contrib import admin
from app.models import Student

class StudentAdmin(admin.ModelAdmin):
    list_display = ['name', 'sex', 'tel']

admin.site.register(Student, StudentAdmin)

二、设计urls

我们编写了下面的urls:

from django.contrib import admin
from django.urls import path
from app import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('students/', views.students),
    path('man/<int:id>/', views.man, name='man'),
    path('woman/<int:id>/', views.woman, name='woman'),
]

这里的students比较好理解,查看所有的学生列表。但是man和woman两条路由的设计就属于特殊需求了,按理说应该直接一条路由即可,不就是查看某个具体学生的信息嘛。

但如果业务需求是这样的:男生和女生必须使用不同的url进行访问!

那就只能这么分开编写成两条路由了。

注意url中的name属性,用于后面的反向路由解析。

三、编写视图

我们编写了下面的视图,很简单:

from django.shortcuts import render
from app import models

def students(request):
    s = models.Student.objects.all()
    return render(request, 'students.html', locals())

def man(request, id):
    student = models.Student.objects.get(id=id)
    return render(request, 'student.html', locals())

def woman(request, id):
    student = models.Student.objects.get(id=id)
    return render(request, 'student.html', locals())

四、HTML模板

首先看看student.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

        <p>name: {{ student.name }}</p>
        <p>sex: {{ student.sex }}</p>
        <p>tel: {{ student.tel }}</p>

</body>
</html>

很简单,就是展示学生的信息,没有需要关注的,仅仅用于表示运行正常,信息显示正确。

重点是students.html(多了个s,复数形式):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h4>欢迎访问liujiangblog.com, 学习更多Django教程</h4>

{% for student in s %}
    {% if student.sex == 'man' %}
        <p>
            姓名:{{ student.name }}   &nbsp;&nbsp;&nbsp;&nbsp;
            详情:<a href="{% url 'man' student.id %}" rel="external nofollow" >{% url 'man' student.id %}</a>
        </p>
    {% else %}
        <p>
            姓名:{{ student.name }}   &nbsp;&nbsp;&nbsp;&nbsp;
            详情:<a href="{% url 'woman' student.id %}" rel="external nofollow" >{% url 'woman' student.id %}</a>
        </p>
    {% endif %}
{% endfor %}

</body>
</html>

通过if标签的判断,决定最终生成的url是哪种。这里使用了Django内置的url模板标签语法。

访问students/页面显示结果:

点击任何一条学生链接都可以正常跳转到详情页面。

五、使用get_absolute_url方法

上面的代码实现了业务需求,男生和女生自动生成了不一样的url,而不是我们惯例的/student/,整个过程也很简单,比较好理解。

但是,这里有个不足之处,那就是区分男女生的逻辑放在了HTML模板文件中,这不是个好的做法,也不优雅。

实际上我们可以使用get_absolute_url方法,在Python代码中实现这一功能。

首先,修改Student模型,添加get_absolute_url方法:

class Student(models.Model):

    sex_choice = [
        ('man', '男性'),
        ('woman', '女性'),
    ]

    name = models.CharField(max_length=128)
    sex = models.CharField(max_length=8, choices=sex_choice)
    tel = models.PositiveIntegerField()

    def __str__(self):
        return self.name

    def get_absolute_url(self):
        from django.urls import reverse
        if self.sex == 'man':
            return reverse('man', args=(self.id,))
        else:
            return reverse('woman', args=(self.id,))

get_absolute_url方法中,我们导入了reverse,这是Django提供的反向解析功能。

reverse能避免我们对url进行硬编码,它接收多种类型的参数,可以是一个视图名,也可以是一个url的name。相关的参数通过args传递,这是一个元组,有顺序。

上面的代码中,通过if/else判断,根据性别的不同,解析出男女生对应的url。

然后,在students.html中,我们就可以修改成下面的样子:

<body>
<h4>欢迎访问liujiangblog.com, 学习更多Django教程</h4>

{% for student in s %}
    <p>
        姓名:{{ student.name }}   &nbsp;&nbsp;&nbsp;&nbsp;
        详情:<a href="{{ student.get_absolute_url }}" rel="external nofollow" >{{ student.get_absolute_url }}</a>
    </p>
{% endfor %}

</body>

首先,没有if/else模板标签了。其次使用{{ student.get_absolute_url }}来代替url模板标签。

student是Student模型类的一个实例,它可以访问类中定义的get_absolute_url方法,从而进入if/else判断,然后根据性别的不同,reverse出不同的url字符串,并在HTML模板中展示出来。

整个HTML模板显得更加简洁优雅,最后的页面结果也是完全一样的。实际上,这里也体现出了Django的模型层和模板层的高度配合。

六、总结思考

例子很简单,无非就是在Student模型中添加了一个get_absolute_url方法。但是如果仔细思考一下我们会发现这里面有很多体现语言特点的东西:

Django本身没有实现一个基本的get_absolute_url方法,在models.Model中也没有get_absolute_url方法的影子,所以这个方法其实只是个思路,没有实质。

get_absolute_url方法本质上只是一个类的实例方法,既然Django内部的代码没有实现它,那么实际上我们可以给它任意命名,比如改成get_url。你可以试试,它绝对能正常工作。但要小心的是,Django核心源码虽然没有定义get_absolute_url方法,在admin后台和feed框架等地方却可能使用了这个get_absolute_url方法,所以在非必须时,不要修改这个方法名。

继续拓展思维,既然可以自定义get_absolute_url方法,那我可不可以在模型中添加任何我需要的实例方法呢?当然可以!并且这是最强大最灵活的方式!比如根据用户的不同,为模型添加一个user_control方法,提供不同的信息,控制访问权限,切换页面主题等等。

到此这篇关于Django的get_absolute_url方法的使用的文章就介绍到这了,更多相关Django get_absolute_url方法内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Django框架教程之正则表达式URL误区详解

    前言 利用Django开发网站,可以设计出非常优美的url规则,如果url的匹配规则(包含正则表达式)组织得比较好,view的结构就会比较清晰,比较容易维护.但这其中可能会有一些误区,下面就来给大家总结下. 问题: 我学习的视频大概是2015年录的,里面用的Django版本比较老关于正则表达式URL这一块都是用的url("url(r'^admin/', admin.site.urls),")方法.而我自己练习的时候是下载的最新版本,而正则表达式URL用的确实path("pat

  • Django URL传递参数的方法总结

    1 无参数情况 配置URL及其视图如下: (r'^hello/$', hello) def hello(request): return HttpResponse("Hello World") 访问http://127.0.0.1:8000/hello,输出结果为"Hello World" 2 传递一个参数 配置URL及其视图如下,URL中通过正则指定一个参数: (r'^plist/(.+)/$', helloParam) def helloParam(reques

  • 获取Django项目的全部url方法详解

    在为一个项目添加权限时,遇到一个问题,就是为项目所有的url设置权限,但是一个一个手动输入太麻烦了,所以考虑用代码获取到一个项目所有的url 首先,考虑到项目最外层的urlpartterns,因为所有的url都要通过这里 urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'^arya/', site.urls), url(r'^index/', index), ] 先循环打印一下这个列表,看一下拿到的结果: <RegexURLRes

  • Django中URL视图函数的一些高级概念介绍

    说到关于请求方法的分支,让我们来看一下可以用什么好的方法来实现它. 考虑这个 URLconf/view 设计: # urls.py from django.conf.urls.defaults import * from mysite import views urlpatterns = patterns('', # ... (r'^somepage/$', views.some_page), # ... ) # views.py from django.http import Http404,

  • Django静态资源URL STATIC_ROOT的配置方法

    缘由 新手学习 Django 当配置好 HTML 页面后,就需要使用一些静态资源,如图片,JS 文件,CSS 样式等,但是 Django 里面使用这些资源并不是直接引用一下就好,还要配置路径即 STATIC_URL 如果这个配置不好的话,请求这些静态资源将返回 HTTP 404 . 经验传授 1. 输出 settings.py 文件里面的 STATIC_URL 到HTML页面,看一下物理路径指向了哪些,通常是不是跑出根目录的.这里给个DEMO: 复制代码 代码如下: def home(reque

  • Django中URL的参数传递的实现

    在Django中有非常强大的URL模块,可以按照开发者的想法来制定清晰的URL,同时支持正则表达式.此外,在URL中还可以传递参数. 1. Django处理请求的方式 1) Django通过URLconf模块来进行判断.通常情况下,这就是ROOT_URLCONF配置的价值,但是如果请求携带了一个urlconf的属性(通常被中间件设置),那么这个被携带的urlconf将会替代ROOT_URLCONF的配置. 2) Django会调用Python模块并寻找各种urlpatterns.这是一个属于dj

  • Django web框架使用url path name详解

    quicktool/view.py文件修改视图函数index(),渲染一个home.html模板 from django.shortcuts import render def index(request): return render(request, 'home.html') quicktool(应用app)下创建一个templates文件夹(模板),在templates下创建一个home.html <!DOCTYPE html> <html> <head> <

  • 在Django中URL正则表达式匹配的方法

    Django框架中的URL分发采用正则表达式匹配来进行,以下是正则表达式的基本规则: 官方演示代码: from django.conf.urls import url from . import views urlpatterns = [ url(r'^articles/2003/$', views.special_case_2003), url(r'^articles/([0-9]{4})/$', views.year_archive), url(r'^articles/([0-9]{4})/

  • Django url,从一个页面调到另个页面的方法

    创建项目和应用 django-admin startproject zqxt_views(项目名) cd zqxt_views python manage.py startapp calc(应用名) ----–1.采用/add?a=4&b=5这样GET方法进行--------- 修改 calc/view.py文件 from django.shortcuts import render from django.http import HttpResponse def add(request): a

  • Django的get_absolute_url方法的使用

    目录 一.创建模型 二.设计urls 三.编写视图 四.HTML模板 五.使用get_absolute_url方法 六.总结思考 本文主要的目的是通过一个简单的例子,展示`get_absolute_url`的用法,抛砖引玉,理解实例方法的本质,能够在不同的业务场景下,灵活多变,完成需求. 环境:Python3.8 + Django3.0 我们都知道,在反向解析url的时候,Django提供了三种方法,帮我们替代硬编码的方式,也就是: 在模板中:使用url模板标签. 在Python代码中:使用re

  • BootStrap扔进Django里的方法详解

    因为django的版本差异化比较大,所以以下配置仅供学习参考. D:\www\mysite>python --version Python 2.7.5 >>> print django.__version__ 1.9.4 本记录不作细说,主要配置过程如下: 1.settings.py最后一段,关于静态文件的配置 # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.9/howto

  • Linux下安装Python3和django并配置mysql作为django默认服务器方法

    我的操作系统为centos6.5 1  首先选择django要使用什么数据库.django1.10默认数据库为sqlite3,本人想使用mysql数据库,但为了测试方便顺便要安装一下sqlite开发包. yum install mysql mysql-devel #为了测试方便,我们需要安装sqlite-devel包 yum install sqlite-devel 2  接下来需要安装Python了,因为Python3已经成为主流,所以接下来我们要安装Python3,到官网去下载Python3

  • Windows下安装Django框架的方法简明教程

    本文实例讲述了Windows下安装Django框架的方法.分享给大家供大家参考,具体如下: 在idea上运行Python项目时,出现了如下错误,这是因为系统中只安装了Python,没有安装Django,有童鞋可能会问,什么是Django,博主的建议是去问度年或谷老师 既然报错的原因就是缺少Django,那我们现在就开始安装这个应用框架. 本站下载Django1.6:Django-1.6.11.tar.gz 官网下载: Django-1.6.11.tar.gz || Django-1.7.11.t

  • python实现合并多个list及合并多个django QuerySet的方法示例

    本文实例讲述了python实现合并多个list及合并多个django QuerySet的方法.分享给大家供大家参考,具体如下: 在用python或者django写一些小工具应用的时候,有可能会遇到合并多个list到一个 list 的情况.单纯从技术角度来说,处理起来没什么难度,能想到的办法很多,但我觉得有一个很简单而且效率比较高的方法是我以前没注意到的.那就是利用 chain 方法来合并多个list. 同样也可以用来合并django 的 QuerySet. 1. python用chain 来合并

  • Gunicorn Django部署配置方法

    1. 简单部署 1. sudo pip3 install gunicorn 2. cd 到django项目中 sudo python3 manage.py migrate 3.启动服务:sudo python3 manage.py runserver 0.0.0.0:8000 4. 使用gunicorn 来运行项目 注:项目名untitled [root@qqc_os7 untitled]# gunicorn untitled.wsgi -b 0.0.0.0:8000 [2019-08-04 0

  • 查看django版本的方法分享

    在cmd输入: python -m django --version 以上这篇查看django版本的方法分享就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们.

  • Django框架安装方法图文详解

    本文实例讲述了Django框架安装方法.分享给大家供大家参考,具体如下: Window 下安装 Django 如果你还未安装Python环境需要先下载Python安装包. 1.Python 下载地址:https://www.python.org/downloads/ 2.Django 下载地址:https://www.djangoproject.com/download/ 注意:目前Django 1.6.x以上版本已经完全兼容Python 3.x. Python 安装(已安装的可跳过) 安装Py

  • python中安装django模块的方法

    网上搜一下对应的版本号,版本号相对应. 安装django有两种方式: 1.pip安装 pip install django 这个方法我用的时候已经报错.貌似访问被阻挡.我一般都用第二种 2.下载压缩包手动安装 在django官网下载tar.gz包,放在python对应目录中解压缩 命令窗口进入压缩包目录后,执行python setup.py install 安装完成后,命令窗口导入django. 可以正常导入且看到版本号即安装成功. 之后就可以创建django项目了.pycharm有免费版和专业

  • Django 项目布局方法(值得推荐)

    一.这种布局的优点 项目中的每个应用都相对独立,方便以后拿出来重用. 这样的布局会促使你在开发过程中考虑每个应用的重用性. 开发.测试.生产等不同的环境都有各自独立的配置文件,方便配置项的共享和定制. 不同的环境都有各自独立的 pip requirements 文件. 每个应用都有各自的 templates 和 static 目录,你可以通过项目级的 templates 和 static 目录中的文件对各应用中的相应内容进行覆盖. 对 models.views.managers 等的测试都各自保

随机推荐