Metis

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

2020-12-15  本文已影响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
上一篇下一篇

猜你喜欢

热点阅读