如何使用ForeignKey为同一模型中的两个单独字段提供字段选择,并指向同一模型?

时间:2018-07-16 03:43:10

标签: python-3.x django-models

从模型表单CustomerCatalog中,我想填写从ProductCatalog模型引用的数据。我知道我可以为其中一个设置单独的模型/表,但这仅意味着我必须在两个单独的位置更新数据。

class CustomerCatalog(models.Model):
"""
"""

id = models.AutoField
account = models.ForeignKey('Account', on_delete=models.SET_NULL, null=True, blank=True, help_text='Account to which this product was sold.')
ccname = models.ForeignKey('ProductCatalog', to_field='name', on_delete=models.SET_NULL, null=True, verbose_name="Product name")
ccproductid = models.ForeignKey('ProductCatalog', on_delete=models.CASCADE, verbose_name="Product ID", related_name='ccpid+')
unit = models.CharField(max_length=50, help_text='Unit of measurement.', null=True, blank=True, default='VM')
unit_price = models.DecimalField(max_digits=30, decimal_places=2, help_text="Enter price per unit.", null=True, blank=True)
total_qty = models.DecimalField(max_digits=30, decimal_places=2, help_text="Enter quantity.", null=True, blank=True)
total_price = models.DecimalField(max_digits=30, decimal_places=2, help_text="Enter total price (note this will be calculated in a future release).", null=True, blank=True)
history = HistoricalRecords()

class Meta:
    verbose_name_plural = 'Customer Catalog'

def __str__(self):
    """
    String for representing the Model object (in Admin site etc.)
    """
    return f'{self.ccname}'


class ProductCatalog(models.Model):
    """
    """

    #UNIT_CHOICES = ('Ea', 'Account', 'VM', 'Hr', 'Project', 'Mbps', 'Rack unit', 'Appliance', 'micro-VM', 'GB')

    servicecat = models.ForeignKey('Service', on_delete=models.SET_NULL, null=True, blank=True, help_text='Enter the service in which this product belongs.')
    id = models.CharField(max_length=40, help_text="Enter Product ID.", primary_key=True)
    name = models.CharField(max_length=100, help_text="Enter name of resource unit that will be used with service definitions.", unique=True)
    billing = models.CharField(max_length=70, help_text="Enter billing type.")
    unit = models.CharField(max_length=80, help_text='Unit of measurement.')
    short_description = models.TextField(max_length=400, help_text="Enter the description of the service.", blank=True)
    version = models.DateField(default=timezone.now, help_text="Enter date of the CPS version.")
    org = models.ForeignKey(OrgUnit, on_delete=models.SET_NULL, null=True, help_text="Enter organization providing the service.")
    history = HistoricalRecords()

    class Meta:
        verbose_name_plural = 'Product Catalog'

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """
        return f'{self.name}'

编辑: 我决定根据Josewails给出的答案在这条路线上走些不同。我认为计算一个字段比我尝试做的要好得多,而且他描述的调用数据的方式告诉了我该怎么做。谢谢。这是我的最终代码:

class CustomerCatalog(models.Model):
    """
    Model for representing products that have been sold and are being used by a specific customer.
    """

    id = models.AutoField(primary_key=True)
    ccproductid = models.ForeignKey('ProductCatalog', on_delete=models.SET_NULL, null=True, verbose_name="Product ID")
    ccname = models.CharField(max_length=255, verbose_name="Product name", blank=True)
    account = models.ForeignKey('Account', on_delete=models.SET_NULL, null=True, blank=True, help_text='Account to which this product was sold.')
    unit = models.CharField(max_length=50, help_text='Unit of measurement.', null=True, blank=True, default='VM')
    unit_price = models.DecimalField(max_digits=30, decimal_places=2, help_text="Enter price per unit.", null=True, blank=True)
    total_qty = models.DecimalField(max_digits=30, decimal_places=2, help_text="Enter quantity.", null=True, blank=True)
    total_price = models.DecimalField(max_digits=30, decimal_places=2, help_text="Enter total price (note this will be calculated in a future release).", null=True, blank=True)
    history = HistoricalRecords()

    @property
    def get_ccname(self):
        return self.ccproductid.name

    def save(self, *args, **kwargs):
        self.ccname = self.get_ccname
        super(CustomerCatalog, self).save(*args, **kwargs)

    class Meta:
        verbose_name_plural = 'Customer Catalog'

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """
        return f'{self.ccproductid}'


class ProductCatalog(models.Model):
    """
    Model to represent the full product portfolio.
    """


    id = models.CharField(max_length=40, help_text="Enter Product ID.", primary_key=True)
    name = models.CharField(max_length=255, help_text="Enter name of resource unit that will be used with service definitions.", unique=True)
    billing = models.CharField(max_length=70, help_text="Enter billing type.")
    unit = models.CharField(max_length=80, help_text='Unit of measurement.')
    short_description = models.TextField(max_length=400, help_text="Enter the description of the service.", blank=True)
    version = models.DateField(default=timezone.now, help_text="Enter date of the CPS version.")
    servicecat = models.ForeignKey('Service', on_delete=models.SET_NULL, null=True, blank=True, help_text='Enter the service in which this product belongs.')
    org = models.ForeignKey(OrgUnit, on_delete=models.SET_NULL, null=True, help_text="Enter organization providing the service.")
    history = HistoricalRecords()

    class Meta:
        verbose_name_plural = 'Product Catalog'

    def __str__(self):
        """
        String for representing the Model object (in Admin site etc.)
        """
        return f'{self.id}'

1 个答案:

答案 0 :(得分:0)

执行此操作的最佳方法是拥有一个ForeignKey字段“ product”,并具有获取名称和ID的方法

就像这样

class ProductCatalog(models.Model):

    product_id = models.CharField(max_length=40, help_text="Enter Product ID.", primary_key=True)
    name = models.CharField(max_length=100,
                            help_text="Enter name of resource unit that will be used with service definitions.",
                            unique=True)


class CustomerCatalog(models.Model):

    product = models.ForeignKey(ProductCatalog, on_delete=models.CASCADE)

    def product_id(self):
        return self.product.product_id

    def product_name(self):
        return self.product.name

注意:您不能有一个名为id的字段,因为它将与Django自己自动生成的id字段冲突。