2017-09-15 49 views
1

我试图检查在一个系统中报告的文件是否存在于不同的系统中。该模型属于不同的表格,在不同的数据库。除了这个名字之外,他们没有任何关系。在Django模型中包含不同表格的值

我使用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)包括被序列化

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) 

,然后我在串行加入我MODEL1性质:

class ProductSerializer(serializers.ModelSerializer): 
    has_fastq = serializers.ReadOnlyField() 
    has_bam = serializers.ReadOnlyField() 
    Meta: 
     model = Product 
+0

'file_format '它是你的'文件'模型的字段吗?我没有看到djang的这样的过滤器,你可以得到链接在文档上,如果它不是字段 –

+0

是的,对不起。我将编辑该字段以便与此处的模型保持一致 – mk2

回答

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) 
+0

看起来不错。我将在星期一尝试,因为我现在无法访问代码。谢谢! – mk2

+0

嘿,我只是将函数'.list'改为'values_list',它的功能就像一个魅力。我编辑你的答案对其他用户都很好。谢谢! – mk2

+0

感谢您的编辑! –