美文网首页Metis
Django ORM中,使用@property装饰器实现关联外键

Django ORM中,使用@property装饰器实现关联外键

作者: 万州客 | 来源:发表于2020-12-15 21:34 被阅读0次

    在Django开发中,有时我们想获取一个实例的关键外键的记录,一般会用Table_set或是related_name作反向查询。那有没有更好的方式呢?本文探索了一种使用@property装饰器结合related_name的方式,更自然的获取到这些信息。

    参考URL:
    https://stackoverflow.com/questions/56907025/how-to-have-a-field-represent-the-count-of-related-objects

    一,Model定义

    以指标集中包含有多少个指标为例,这都是老熟客了哈。

    from django.db import models
    from django.contrib.auth import get_user_model
    
    User = get_user_model()
    
    
    # 指标集
    class ViewSet(models.Model):
        view_id = models.CharField(max_length=64,
                                   verbose_name='指标集id')
        view_name = models.CharField(max_length=64,
                                     verbose_name='指标集名称')
        create_date = models.DateTimeField(auto_now_add=True, verbose_name='新建时间')
        update_date = models.DateTimeField(auto_now=True, verbose_name='更新时间')
        status = models.BooleanField(default=True, verbose_name='状态')
    
        def __str__(self):
            return self.view_name
    
        @property
        def username(self):
            return self.create_user.username
        
        # 这里是关键,用于获取每一个指标集实例里含有的指标数量,orm语句书写即可。
        @property
        def attr_count(self):
            return self.ra_attr.count()
    
        class Meta:
            db_table = 'ViewSet'
            ordering = ('-update_date', )
    
    
    # 指标
    class Attr(models.Model):
        attr_id = models.CharField(max_length=64,
                                   verbose_name='指标id')
        attr_name = models.CharField(max_length=64,
                                     verbose_name='指标名称')
        view_set = models.ForeignKey(ViewSet,
                                     related_name='ra_attr',
                                     on_delete=models.CASCADE,
                                     verbose_name='指标集')
        create_date = models.DateTimeField(auto_now_add=True, verbose_name='新建时间')
        update_date = models.DateTimeField(auto_now=True, verbose_name='更新时间')
        status = models.BooleanField(default=True, verbose_name='状态')
    
        @property
        def username(self):
            return self.create_user.username
    
        @property
        def view_set_name(self):
            return self.attr.view_set.view_name
    
        def __str__(self):
            return self.attr_name
    
        class Meta:
            db_table = 'Attr'
            ordering = ('-update_date',)
    

    指标Attr中有外键view_set 指向指标集ViewSet,related_name为ra_attr。我们在ViewSet中增加一个attr_count字段,使用@property装饰。使用self.ra_attr.count()这样的ORM语句,就可以获取到每一个指标集包含的指标的数量了。
    二,序列化

    from rest_framework import serializers
    from MetisModels.models import ViewSet
    
    
    class ViewSetSerializer(serializers.ModelSerializer):
        class Meta:
            model = ViewSet
            # fields = '__all__'
            fields = ['id', 'view_id', 'view_name', 'attr_count',  'update_date']
            extra_kwargs = {
                'attr_count': {
                    'read_only': True,
                },
                'update_date': {
                    'read_only': True,
                }
            }
    

    这里将ViewSet中的attr_count作为显示字段(read_only),返回给前端。

    三,前端ajax请求获取到的样例数据

    (5) [{…}, {…}, {…}, {…}, {…}]
    0: {id: 215, view_id: "1005", view_name: "数据库性能", all_attrs: 0, update_date: "2020-12-09T22:02:10.370967+08:00"}
    1: {id: 214, view_id: "1004", view_name: "中间件连接", all_attrs: 2, update_date: "2020-12-09T22:02:10.366965+08:00"}
    2: {id: 213, view_id: "1003", view_name: "用户登陆", all_attrs: 1, update_date: "2020-12-09T22:02:10.362964+08:00"}
    3: {id: 212, view_id: "1002", view_name: "网络流量", all_attrs: 2, update_date: "2020-12-09T22:02:10.358964+08:00"}
    4: {id: 211, view_id: "1001", view_name: "系统性能", all_attrs: 2, update_date: "2020-12-09T22:02:10.353963+08:00"}
    length: 5
    __proto__: Array(0)
    

    可以看到,all_attrs字段里,显示了每一个指标集拥有的指标的数量,快速规范!

    四,vue前端可以展示的样子

    2020-12-15 21_33_43-Admin _ 指标管理.png

    相关文章

      网友评论

        本文标题:Django ORM中,使用@property装饰器实现关联外键

        本文链接:https://www.haomeiwen.com/subject/wlkggktx.html