在django模型

时间:2017-09-15 19:39:36

标签: django django-models django-rest-framework

我正在尝试检查一个系统中报告的文件是否存在于不同的系统中。这些模型属于不同数据库中的不同表。他们没有共同名称之外的任何关系。

我正在使用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

1 个答案:

答案 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)