使用信号检测Django中的保存操作时,对象中未显示的多对多字段 [英] Many to many field not shown in object while using signals to detect save operation in django

查看:84
本文介绍了使用信号检测Django中的保存操作时,对象中未显示的多对多字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是以下问题的后续问题:

意图:创建Person的实例时,我想生成一个License对象.因此,我筛选出添加到License中的最后一个元组,然后使用其内容来生成License实例.

def generate_license():
    import pdb
    pdb.set_trace()
    man = Person.objects.filter().order_by('-time_added')[:1][0] # Restricting the filter to one query and then taking the value at the 0th index. order_by '-time_added' gives the latest tuple at the top.
    license = License.objects.create(...Info about car, person...)

错误:

一个例子: 假设Car有3个实例:

  1. 宝马
  2. 法拉利
  3. 兰博基尼

现在,当我从管理员添加Person实例时,例如:

per是具有car = BMW, FERRARIname = Bob的实例 当我在管理员中单击save时,set_trace()启动.因此,在generate_license中进行查询之后:

pdb中,当执行查询时,我尝试打印出per.car.all(),但是它给了我[],而当我尝试打印出per.name时,它确实打印出了Bob.因此,我真的不太了解per.name的保存方式和per.car isnt的方式.

此外,当请求完成时,即我已经按下pdb中的c,我再次单击同一实例的保存,这一次它完美地读取了per.car.all(),而如果在保存之前,我添加了LAMBORGHINI,仅显示BMWFERRARI.因此,我猜正在发生的是many-to-many字段迟到了一个请求.尽管我无法指出原因.需要一些帮助.我想念什么吗?

问题:是否存在从create signal识别update signal的特定方法?我的意思是我不想每次数据更新时都生成一个新的License.仅在创建数据后才会生成新的License.那么,如何区分updatesave信号?

解决方案

post_save不适用于m2m字段.您必须使用 m2m_changed信号.

类似这样的东西:

def my_m2m_signal(sender, **kwargs):
    action = kwargs.get('action')
    if action == 'post_add':
        print 'post_add is activated on m2m'

signals.m2m_changed.connect(my_m2m_signal, sender=Person.car.through)

This is a follow up question to : Cant get post_save to work in Django

My models are :

class Car(models.Model):
    name = models.CharField(max_length=50)
    ...
    some other attributes of Car
    ...

class Person(models.Model):
    car = models.ManyToManyField(Car)
    name = models.CharField(max_lenght=100)
    ...
    Some other attributes of Person
    ...


class License(models.Model):
    person = models.ForeignKey(Person)
    ...
    Other attributes of License
    ...

Signal handler:

def signal_handler(sender, **kwargs):
    print 'Person saved!'
    generate_license()

post_save.connect(signal_handler, sender=Person, dispatch_uid="Unique person")

The intent: When an instance of Person is created, I want to generate a License object. So I filter out the last tuple that was added into License and then use its contents to generate a License instance.

def generate_license():
    import pdb
    pdb.set_trace()
    man = Person.objects.filter().order_by('-time_added')[:1][0] # Restricting the filter to one query and then taking the value at the 0th index. order_by '-time_added' gives the latest tuple at the top.
    license = License.objects.create(...Info about car, person...)

The Error:

An example: Say Car has 3 instances:

  1. BMW
  2. FERRARI
  3. LAMBORGHINI

Now when I add an instance of Person from the admin, example:

per be an instance with car = BMW, FERRARI and name = Bob When I click save in admin, the set_trace() starts. So after the query in generate_license :

In pdb, when the query executes, I try printing out per.car.all() but it gives me [] and when I try printing out per.name, it does print out Bob. So I am not really getting as to how per.name is saved and per.car isnt.

Also, when the request is completed, that is I have pressed c in pdb, I again click on save for the same instance, this time it reads the per.car.all() perfectly while if before saving, I added LAMBORGHINI, it only shows up BMW and FERRARI. So what I guess is happening is that the many-to-many field is coming a request late. Although I can't point out the reason for this. Need some help. Am I missing something?

Question: Is there a specific way to identify an update signal from a create signal? I mean I do not want to generate a new License every time a data is updated. A new License will only generate when the data has been created. So, how to distinguish between update and save signals?

解决方案

post_save does not work on m2m fields. You have to use the m2m_changed signal.

Something like this:

def my_m2m_signal(sender, **kwargs):
    action = kwargs.get('action')
    if action == 'post_add':
        print 'post_add is activated on m2m'

signals.m2m_changed.connect(my_m2m_signal, sender=Person.car.through)

这篇关于使用信号检测Django中的保存操作时,对象中未显示的多对多字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆