问题
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:
- BMW
- FERRARI
- 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?
回答1:
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)
来源:https://stackoverflow.com/questions/17263780/many-to-many-field-not-shown-in-object-while-using-signals-to-detect-save-operat