在django模型保存方法

时间:2017-05-24 10:18:25

标签: django django-models django-forms django-views django-admin

我正在尝试将数据添加到Django admin的表格 BillRecord 。我需要在模型保存中访问 ManytoMany 字段的选定值方法和需要根据ManytoMany字段的选定对象做一些逻辑。

class ProductType(BaseApplicationModel):
   name = models.CharField(max_length=128)

class Product(BaseApplicationModel)
   type = models.ForeignKey(ProductType,related_name="products")

class BillRecord(BaseApplicationModel):
    products = models.ManyToManyField(Product, related_name="billrecords")

    def save(self, *args, **kwargs):
       super(BillRecord, self).save(*args, **kwargs)
       for product in self.products.all():
          print product

在我尝试打印产品值的代码中,它为billing.Product.None self.products.all()返回空查询集

我需要在ManyToMany字段选择框中获取所选对象的ID。 picture

2 个答案:

答案 0 :(得分:0)

问题是当BillRecord实例与Product相关联时, 总是 保存 。通过多对多关系,您可以先保存任何对象。处理它的正确方法是使用m2m-changed signal

  

在模型实例上更改ManyToManyField时发送。严格来说,这不是模型信号,因为它是由ManyToManyField发送的,但由于它在跟踪模型的更改时补充了pre_save / post_save和pre_delete / post_delete,因此它包含在此处。

所以你应该尝试以下内容:

from django.db.models.signals import m2m_changed

...your models here...

def products_changed(sender, **kwargs):
    # Do something here
    pass

m2m_changed.connect(products_changed, sender=BillRecord.products.through)

答案 1 :(得分:0)

m2m中有三种操作:添加,删除,清理

信号@receiver(m2m_changed,sender = Model.manytomanyfield.through)重复操作:

第一:

删除前和删除后:如果从manytomanyfield中删除了某些对象 然后要进行预添加,您可以在此处访问您选择的(新)值和实例(具有manytomanyfield的已删除对象)。 您可以编写类似的内容来获取它们:

@receiver(m2m_changed, sender=ProductVariation.combination.through)

def check_attribute(sender,** kwargs): 实例= kwargs ['instance']

import pdb; pdb.set_trace()
if kwargs['action'] == 'pre_add':
    if kwargs.get('pk_set'):
        product_attributes = instance.combination.all() | \
                             ProductAttribute.objects.filter(id__in=kwargs.get('pk_set'))
        groups_count = product_attributes.values('attribute').annotate(Count('id'))
        for group in groups_count:
            if group.get('id__count', 0) > 1:
                attribute_name = Attribute.objects.get(id=group['attribute'])
                rai