【问题标题】:Django alter admin save to alter another table fieldDjango alter admin save 更改另一个表字段
【发布时间】:2020-04-05 23:32:59
【问题描述】:

我正在创建一个包含基本库存系统的 django 站点。其中包括以下型号

class Stock(models.Model):
    # Fields
    location = models.ForeignKey(Location)
    product = models.ForeignKey(Product)
    quantity = models.IntegerField()

class Transfer(models.Model):
    # Fields
    location1 = models.ForeignKey(Location, related_name='location1')
    location2 = models.ForeignKey(Location, related_name='location2')
    date_transferred = models.DateField(default=timezone.now)

class TransferLine(models.Model):
    # Choice set
    direction_set = (
        ('1TO2', 'From 1 to 2'),
        ('2TO1', 'From 2 to 1')
    )

    # Fields
    transfer = models.ForeignKey(Transfer, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
    quantity = models.IntegerField()
    transfer_direction = models.CharField(max_length=4, choices=direction_set, default='1TO2')

当我创建新的转移时,我希望能够从 Stock 模型中的数量中自动扣除和添加 TransferLine 中的产品。

我已经知道如何在 admin.py 文件中为 TransferAdmin 类覆盖 save_model 方法,但我不知道如何从 SaleAdmin 类中访问 Stock 模型。

这可以在管理员中完成吗?我必须创建自己的表单吗?我真的很想从管理员那里做到这一点,因为与在自定义构建的表单中相比,inlinetabular 在管理员中真的很容易做到。 (至少从我能找到的情况来看。)

对此的任何帮助将不胜感激。

为了帮助澄清,假设我的数据库有以下股票:

|id |loc_id|prod_id|qty|
|:-:|:----:|:-----:|:-:|
|1  |1     |1      |6  |
|1  |2     |1      |6  |

然后我填写交易表格,将产品 1 的 3 个从位置 1 转移到位置 2。我想在保存交易表格后将 Stock 表更新为以下内容。

|id |loc_id|prod_id|qty|
|:-:|:----:|:-----:|:-:|
|1  |1     |1      |3  |
|1  |2     |1      |9  |

谢谢你, 迈克尔

【问题讨论】:

  • Django 信号可能有助于完成这项任务。所以概念是,在你的 signals.py 中,你必须添加一个涉及 post_save 的函数。
  • @jerome_mjt:我不认为你可以用信号做到这一点。模型保存后信号的 Django 文档指出,“不应查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态。”我误会那句话了吗?
  • 哦,是的。你可以重写 stock 模型的 save 方法并将逻辑放入其中。

标签: django django-forms django-admin


【解决方案1】:
class Transfer(models.Model):
    # Fields
    location1 = models.ForeignKey(Location, related_name='location1')
    location2 = models.ForeignKey(Location, related_name='location2')
    date_transferred = models.DateField(default=timezone.now)

    def save(self, *args, **kwargs):
        created = False
        if not self.id:
            created = True
        super().save(*args, **kwargs)
        if created:
            # will execute after the creation
            transfer_line = TransferLine.objects.create(transfer=self)  # self = created tranfer

【讨论】:

  • 这如何让我访问 Stock 模型?我没看到。
  • transfer_line.product.stock_set.all()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-03-06
  • 2019-03-22
  • 2015-04-29
相关资源
最近更新 更多