Django ORM中,使用@property装饰器实现关联外键
2020-12-15 本文已影响0人
万州客
在Django开发中,有时我们想获取一个实例的关键外键的记录,一般会用Table_set或是related_name作反向查询。那有没有更好的方式呢?本文探索了一种使用@property装饰器结合related_name的方式,更自然的获取到这些信息。
一,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字段里,显示了每一个指标集拥有的指标的数量,快速规范!