Django Admin - 如何从其他表中提取模型默认字段值

时间:2015-04-19 14:38:36

标签: django admin

我正在尝试从不同的表中自动获取字段值。以下是我的情况:我有两个表:销售和退货。在输入新的退货时,当选择“sales_id”时,想要显示“sales_quantity”自动填充,不可编辑(并且如果可能,还要约束“return_quantity”< =“sales_quantity”)。

class T_Sales(models.Model):
    product = models.ForeignKey(P_Product)
    sales_quantity = models.IntegerField()
    def __unicode__(self):             
        return str(self.id)

class T_Return(models.Model):
    sales_id = models.ForeignKey(T_Sales)
    #sales_quantity = models.IntegerField(default=T_Sales.sales_quantity)
    return_quantity = models.IntegerField()
    def __unicode__(self):             
        return self.description

2 个答案:

答案 0 :(得分:0)

在模型中创建属性可以完成任务。 sales_id不会为空,因此在尝试获取该值时永远不会出现问题。

class T_Sales(models.Model):
    product = models.ForeignKey(P_Product)
    sales_quantity = models.IntegerField()
    def __unicode__(self):             
        return str(self.id)

class T_Return(models.Model):
    sales_id = models.ForeignKey(T_Sales)
    return_quantity = models.IntegerField()
    def __unicode__(self):             
        return self.description

    @property
    def sales_quantity(self):
        return self.sales_id.sales_quantity

该方法的优点:

  • 值未存储在您的数据库中两次
  • 如果T_Sales对象发生更改,
  • 值将自动更新。

该方法的缺点:

  • 除非在查询集中使用select_related,否则在获取该字段时会触发单独的查询。
  • 很难(但可能)在django admin中的详细视图中打印该字段(您始终只能在列表中显示)。

如果你不想创建一些验证,你可以覆盖模型的clean方法并在这里进行比较,如果有问题,你应该抛出ValidationError。例如:

from django.core.exceptions import ValidationError

class T_Return(models.Model):

    # ......

    def clean(self):
        if self.return_quantity > self.sales_quantity:
            raise ValidationError("You can't return more than it was bought")
        return super(T_Return, self).clean()

您还可以将错误分配给return_quantity字段,只需将表单'field_name': error中的字典传递给验证错误:

            raiseValidationError({'return_quantity': _('You can't return more than it was bought.')}

您无法将该错误分配给sales_quantity

答案 1 :(得分:0)

您可以在T_Return模型中创建单独的字段,并在保存时从T_Sales复制值:

class T_Sales(models.Model):
    product = models.ForeignKey(P_Product)
    sales_quantity = models.IntegerField()
    def __unicode__(self):             
        return str(self.id)

class T_Return(models.Model):
    sales_id = models.ForeignKey(T_Sales)
    sales_quantity = models.IntegerField(editable=False)
    return_quantity = models.IntegerField()
    def __unicode__(self):             
        return self.description

    def save(self, *args, **kwargs):
        if not self.sales_quantity:
            self.sales_quantity = self.sales_id.sales_quantity
        supr(T_Return, self).save(*args, **kwargs)

该方法的优点:

  • 仅在(第一次)保存时会触发T_Sales的其他查询。
  • 在管理员的详细信息视图中显示值很容易

该方法的缺点:   - 您将值存储在数据库中两次   - 如果T_Sales对象中的值发生变化,T_Return中的值将不会自动更改(可以通过保存T_Sales时通过简单触发修复,但仅限于django ORM内部<) / p>

如果你不想创建一些验证,你可以覆盖模型的clean方法并在这里进行比较,如果有问题,你应该抛出ValidationError。例如:

from django.core.exceptions import ValidationError

class T_Return(models.Model):

    # ......

    def clean(self):
        if self.return_quantity > self.sales_quantity:
            raise ValidationError("You can't return more than it was bought")
        return super(T_Return, self).clean()

您还可以将错误分配给return_quantitysales_quantity字段,只需将表单'field_name': error中的dict传递给验证错误:

            raiseValidationError({'return_quantity': _('You can't return more than it was bought.')}

将错误信息分配到return_quantitysales_quantity都会显示错误两次。