如何避免重复创建对象

时间:2018-10-05 15:50:13

标签: python django

我现在有重复问题,我不知道前进的方向需要帮助 我的这个模型分支与库存有反向关系

class Branch(models.Model):
    name = models.CharField(
        'Branch',
        unique=True,
        max_length=10,
        validators=[MinLengthValidator(5)])
    location = models.TextField(max_length=650,
        blank=True,
        help_text='location of the linsan branch')


    class Meta:
        verbose_name_plural = 'Branch'

    def __str__(self):
        return self.name 

class Stock(models.Model):
    branch          = models.ForeignKey(
        Branch,
        related_name = 'branch',
        help_text='Enter the name of the branch',
        on_delete=models.CASCADE,
        blank=False,
        null=False
        )

    manufacturers_name = models.CharField(
        max_length=50, 
        blank=True)

    description        = models.CharField(
        max_length=50,
        help_text='Enter the name of the product here',
        unique=True
        )

    model_number    = models.CharField(
        max_length=25,
        blank=True,
        null=True,
        help_text='Enter the model number of the item if any')

    color           = models.CharField(
        max_length=20,
        default='black',
        blank=True,
        null=True,)
    quantity        = models.PositiveIntegerField(
        validators=[validate],
        verbose_name='Quantity In stock')

    retail_price    = MoneyField(
        max_digits=14,
        decimal_places=2,
        default_currency='NGN',
        blank=False,
        verbose_name="Retail Price")

    customer_price  = MoneyField(
        max_digits=14,
        decimal_places=2,
        default_currency='NGN',
        blank=False)

    added = models.DateTimeField(
        auto_now_add=True, 
        help_text='The date the product was added')
    image           = models.ImageField(
        blank=True,
        null=True,
        upload_to='uploads/%Y/%m/%d/',
        help_text='Upload the image of the product if any')
    history = HistoricalRecords()
    class Meta:
        ordering = ['description']


    def __str__(self):
        return self.description

还有一个带有外键库存的模型

class WaybillItem(models.Model):
    waybill = models.ForeignKey(Waybill,
        on_delete=models.CASCADE,
        related_name='waybill_item')
    product = models.ForeignKey(
        'stock.Stock',
        on_delete=models.CASCADE,
        blank=False,
        null=False)
    quantity = models.PositiveIntegerField(validators=[validate, MinValueValidator(1)])

在我的股票应用中,我有一个信号,如果不存在,我想向另一个分支创建新的股票对象。

def update_stock_on_waybill(sender, instance, **kwargs):
    transferred_to = instance.waybill.transferred_to.branch.all()
    product = instance.product

    if product in transferred_to:
        print("it is!")
        pass
    else:
        print("it isn't")
        Stock.objects.create(
            branch=instance.product.branch,
            description=instance.product.description,
            model_number=instance.product.model_number,
            color=instance.product.color,
            quantity=instance.quantity,
            retail_price=instance.product.retail_price,
            customer_price=instance.product.customer_price
            )
    product.save()

    pre_save.connect(update_stock_on_waybill, sender=WaybillItem)

但是每次我保存一个不存在的新运单(**我排除了模型)时,它都会创建一个新对象,这很好,但是如果该对象确实存在,则同样适用,我对python,django还是比较陌生,总体而言,我只是在开始编程时,会因此而大为感激,推动,朝着正确的方向前进。我将继续在该站点上搜索类似内容,我相信有人可能偶然发现了类似内容。感谢adv

2 个答案:

答案 0 :(得分:1)

要完成所需的操作,可以向第一遍添加布尔检查。

def update_stock_on_waybill(sender, instance,is_create, **kwargs):

    transferred_to = instance.waybill.transferred_to.branch.all()
    product = instance.product

    if is_create:
        print("it is!")
        pass
    else:
        print("it isn't")
        Stock.objects.create(
            branch=instance.product.branch,
            description=instance.product.description,
            model_number=instance.product.model_number,
            color=instance.product.color,
            quantity=instance.quantity,
            retail_price=instance.product.retail_price,
            customer_price=instance.product.customer_price
            )
        is_create = True
    product.save()

    pre_save.connect(update_stock_on_waybill, sender=WaybillItem)
    return is_create

我添加了is_create作为函数的参数,检查和返回。可以将is_created设置为该函数范围之外的变量,然后在每次调用它时将其传递给该函数。

如此

out_scope_created = False
out_scope_created = update_stock_on_waybill(sender,instance,out_scope_created)

答案 1 :(得分:0)

我对类似情况的处理有些不同。 我在对象创建中添加了一组现有项(对象的标识符)。 如果新对象已经存在,那么我将在类中的 init 失败。

class firstone:
    def __init__(self,name:str,chk:set):
        if name in chk:
            raise ValueError
        self.name = name
        chk.add(name)

    def get_name(self) -> str:
        return self.name

创建一个集合并实例化第一个对象。

nmset=set()
a=firstone("a",nmset)

a.get_name()

返回“ a”

nmset

仅包含“ a”的返回集

b=firstone("a",nmset)

抛出ValueError,无论哪种方式都可以处理。

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-17-312c2fbf49eb> in <module>
----> 1 b=firstone("a",nmset)

<ipython-input-13-660b12b68b44> in __init__(self, name, chk)
      2     def __init__(self,name:str,chk:set):
      3         if name in chk:
----> 4             raise ValueError
      5         self.name = name
      6         chk.add(name)

ValueError: 

缺点是必须通过集合,但是当只有很多地方可以从中实例化对象时,我发现这是一种更简单的方法。