Django的get_absolute_url方法的使用
admin
2023-05-01 07:11:50
目录

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

    环境:Python3.8 + Django3.0

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

    前面两种方式比较常见,我们也很熟悉,但是最后的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//', views.man, name='man'),
        path('woman//', 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

    
    
    
        
        Title
    
    
    
            

    name: {{ student.name }}

    sex: {{ student.sex }}

    tel: {{ student.tel }}

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

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

    
    
    
        
        Title
    
    
    

    欢迎访问liujiangblog.com, 学习更多Django教程

    {% for student in s %} {% if student.sex == 'man' %}

    姓名:{{ student.name }}      详情:{% url 'man' student.id %}

    {% else %}

    姓名:{{ student.name }}      详情:{% url 'woman' student.id %}

    {% endif %} {% endfor %}

    通过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中,我们就可以修改成下面的样子:

    
    

    欢迎访问liujiangblog.com, 学习更多Django教程

    {% for student in s %}

    姓名:{{ student.name }}      详情:{{ student.get_absolute_url }}

    {% endfor %}

    首先,没有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方法内容请搜索趣讯吧以前的文章或继续浏览下面的相关文章希望大家以后多多支持趣讯吧!

    相关内容

    热门资讯

    苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
    北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
    世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
    长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
    应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
    猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
    猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
    阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
    脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
    demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
    苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
    北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
    应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
    长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
    世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
    阿西吧是什么意思 阿西吧相当于... 即使你没有受到过任何外语培训,你也懂四国语言。汉语:你好英语:Shit韩语:阿西吧(아,씨발! )日...
    脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
    demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
    北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...