Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/django/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django模型中自定义相关字段,指定要通过_Python_Django_Foreign Key Relationship_Django Custom Manager - Fatal编程技术网

Python 在Django模型中自定义相关字段,指定要通过

Python 在Django模型中自定义相关字段,指定要通过,python,django,foreign-key-relationship,django-custom-manager,Python,Django,Foreign Key Relationship,Django Custom Manager,在我的Django项目中,我有一个如下产品模型: class Manufacturer(models.Model): name = models.CharField(max_length=100) class Product(models.Model): manufacturer = models.ForeignKey('Manufacturer') # .favorite_set: ManyToOne relation coming from the # 'F

在我的Django项目中,我有一个如下产品模型:

class Manufacturer(models.Model):
    name = models.CharField(max_length=100)

class Product(models.Model):
    manufacturer = models.ForeignKey('Manufacturer')
    # .favorite_set: ManyToOne relation coming from the
    # 'Favorite' class (shown a couple of lines below)
class Favorite(models.Model):
    user = models.ForeignKey(User)
    product = models.ForeignKey('Product')

    class Meta:
        unique_together = ('user', 'product',)
class ProductSearch(models.Model):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
class ProductSearch(BaseModel):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
    product_favorite_set = models.ManyToManyField('Favorite', related_name='+',
                                              through='Favorite',
                                              through_fields=['product']
                                              )
我的网站的用户可以将某些产品标记为收藏夹。为了提供此功能,我有一个Django模型,如下所示:

class Manufacturer(models.Model):
    name = models.CharField(max_length=100)

class Product(models.Model):
    manufacturer = models.ForeignKey('Manufacturer')
    # .favorite_set: ManyToOne relation coming from the
    # 'Favorite' class (shown a couple of lines below)
class Favorite(models.Model):
    user = models.ForeignKey(User)
    product = models.ForeignKey('Product')

    class Meta:
        unique_together = ('user', 'product',)
class ProductSearch(models.Model):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
class ProductSearch(BaseModel):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
    product_favorite_set = models.ManyToManyField('Favorite', related_name='+',
                                              through='Favorite',
                                              through_fields=['product']
                                              )
在该模型中,
.product
外键在
产品
模型中创建一个名为
收藏集
的反向关系。这一切都很好,也很有用:当我收到一个用户的HTTP请求来检索产品时,我可以通过这样做很容易地判断它是否受到特定用户的青睐:

product = Product.objects.get(id='whatever_id')
is_favorited = bool(product.favorite_set.filter(user=self.user).count() == 1)
# or probably:
#   is_favorited = product.favorite_set.filter(user=self.user).exists()
# 
现在,我有另一个严重非规范化的模型(即SQL非规范化),我想用于快速文本搜索

此模型“假装”为产品,但将通过“常规”产品的FK关系找到的数据包含到模型本身中。大概是这样的:

class Manufacturer(models.Model):
    name = models.CharField(max_length=100)

class Product(models.Model):
    manufacturer = models.ForeignKey('Manufacturer')
    # .favorite_set: ManyToOne relation coming from the
    # 'Favorite' class (shown a couple of lines below)
class Favorite(models.Model):
    user = models.ForeignKey(User)
    product = models.ForeignKey('Product')

    class Meta:
        unique_together = ('user', 'product',)
class ProductSearch(models.Model):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
class ProductSearch(BaseModel):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
    product_favorite_set = models.ManyToManyField('Favorite', related_name='+',
                                              through='Favorite',
                                              through_fields=['product']
                                              )
这个类有自己的
id
字段(因为它是Django模型),并且,正如您在上面看到的,它将与产品有
OneToOne
关系(其中一个
ProductSearch
条目链接到一个且只有一个
Product

由于这个模型,如果我想搜索制造商为“福特”的产品(例如),我不需要将
产品
表与
制造商
表连接起来。我可以直接在
ProductSearch
中进行查找,并节省几毫秒的时间

由于
ProductSearch
旨在与
Product
兼容,因此我还尝试将
ProductSearch
类中“自然”出现的
收藏集
建模到该
ProductSearch
模型中

这就是困难所在:我不知道怎么做:-)

理想情况下,我会有:

class ProductSearch(models.Model):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    manufacturer_name = models.CharField(max_length=100)
    #
    # Couldn't find anything to do the following:
    product_favorite_set = models.ManyToOneField('Favorite',
                                                 through_fields=('product',))
但我没能做到

我曾试图像这样“滥用”过
ManyToManyField

class Manufacturer(models.Model):
    name = models.CharField(max_length=100)

class Product(models.Model):
    manufacturer = models.ForeignKey('Manufacturer')
    # .favorite_set: ManyToOne relation coming from the
    # 'Favorite' class (shown a couple of lines below)
class Favorite(models.Model):
    user = models.ForeignKey(User)
    product = models.ForeignKey('Product')

    class Meta:
        unique_together = ('user', 'product',)
class ProductSearch(models.Model):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
class ProductSearch(BaseModel):
    product = models.OneToOneField('Product', 
                                   on_delete=models.CASCADE,
                                   related_name='searcher')
    product_name = models.CharField(max_length=100)
    manufacturer_name = models.CharField(max_length=100)
    product_favorite_set = models.ManyToManyField('Favorite', related_name='+',
                                              through='Favorite',
                                              through_fields=['product']
                                              )
但这会在系统检查时产生错误:

api.Favorite: (fields.E336) The model is used as an intermediate model
              by 'api.ProductSearch.product_favorite_set', but it
              does not have a foreign key to 'ProductSearch' or 'Favorite'.
api.ProductSearch.product_favorite_set: (fields.E339) 'Favorite.product'
              is not a foreign key to 'ProductSearch'.
我想我可以将
产品\u favorite\u集
设置为Python
@属性
,然后在其中执行自定义查询,如:

class ProductSearch(BaseModel):
     # ....
     @property
     def product_favorite_set(self):
           return Favorite.objects.filter(product=self.product)
但我想知道我是否可以使用“纯”Django工具来实现这一点(只有出于好奇)


任何帮助都将不胜感激。提前谢谢。

您不需要对关系进行建模。对于
ProductSearch
ps
ps.product.favorite\u set
实例,您可以使用。@ShikharChauhan感谢您的评论。但是,
ps.product.favorite\u集
将在
ProductSearch
product
之间生成一个连接,这是我想要避免的(出于性能目的)ProductSearch实例指向一个product实例,而该实例又有一个favorite\u集,因此不需要显式指定它。如果您打印django用于此查找的查询,您将看到这些表正在被连接起来。。哈哈。。在我发布我的评论后,我看到了你的编辑,所以我依次编辑了:)如果有适当的索引,连接不是问题。你不需要建立关系模型。对于
ProductSearch
ps
ps.product.favorite\u set
实例,您可以使用。@ShikharChauhan感谢您的评论。但是,
ps.product.favorite\u集
将在
ProductSearch
product
之间生成一个连接,这是我想要避免的(出于性能目的)ProductSearch实例指向一个product实例,而该实例又有一个favorite\u集,因此不需要显式指定它。如果您打印django用于此查找的查询,您将看到这些表正在被连接起来。。哈哈。。在我发布我的评论后,我看到了你的编辑,所以我依次编辑了它:)如果有适当的索引,连接不是问题。