我正在尝试检查一个系统中报告的文件是否存在于不同的系统中。这些模型属于不同数据库中的不同表。他们没有共同名称之外的任何关系。
我正在使用django rest框架来序列化一个表的值,我想以一种有效的方式包含另一个表的值。我目前正在做的方式,提出太多查询!我的问题是:有没有办法改善这个性能问题?
以下是我所拥有的一个例子
# model1
class Product(models.Model):
name = models.CharField(max_length=50)
# model2 (different database)
class Files(models.Model):
name = models.CharField(max_length=50)
filename = models.CharField(max_length=50)
我的观点设置是
class ProductViewSet(viewsets.ModelViewSet):
queryset = Inventory.objects.all()
serializer_class = ProductSerializer
我设法以两种不同的方式得到了结果(尽管不是很有效):
1)包括序列化器中的字段
class ProductSerializer(serializers.ModelSerializer):
has_png = serializers.SerializerMethodField('has_png')
has_jpg = serializers.SerializerMethodField('has_jpg')
def has_png(self, product):
# I wish I could avoid this code duplication too...
# I'm basically using the same code in two functions
files = Files.objects.filter(name=product.name)
filtered_files = files.filter(filename__startswith='png')
return filtered_files.exists()
def has_bam(self, product):
files = Files.objects.filter(name=product.name)
filtered_files = files.filter(filename__istartswith='jpg')
return filtered_files.exists()
Meta:
model = Product
2)在我的model1中包含序列化的属性
class Product(modes.Model):
name = models.CharField(max_length=50)
def _get_png(self):
# I tried to cache this query in a different function but didn't work
files = Files.objects.filter(name=self.name)
filtered_files = files.filter(filename__istartswith='png')
return filtered_files.exists()
def _get_jpg(self):
files = Files.objects.filter(name=self.name)
filtered_files = files.filter(filename__istartswith='jpg')
return filtered_files.exists()
has_png = property(_get_png)
has_jpg = property(_get_jpg)
然后我添加了序列化程序:
class ProductSerializer(serializers.ModelSerializer):
has_fastq = serializers.ReadOnlyField()
has_bam = serializers.ReadOnlyField()
Meta:
model = Product
答案 0 :(得分:1)
您可以尝试使用cached_property
from django.db.models.functions import Lower
from django.utils.functional import cached_property
class Product(modes.Model):
name = models.CharField(max_length=50)
@cached_property
def file_formats(self):
files = Files.objects.filter(name=self.name)
files = files.annotate(lower_format=Lower('file_format')))
return files.values_list('lower_format', flat=True)
def _get_png(self):
return 'png' in self.file_formats
def _get_jpg(self):
return 'jpg' in self.file_formats
has_png = property(_get_png)
has_jpg = property(_get_jpg)