2009-09-03 21 views

Odpowiedz

2

Jednym ze sposobów jest hak do `„inline sygnału pre_save Twojego modelu:

from django.db.models.signals import pre_save 
from your_app.models import YourModel 

def callback(sender, **kwargs): 
    # 'instance' is the model instance that is about to be saved, 
    # so you can do whatever you want to it. 
    instance.field = new_value 

pre_save.connect(callback, sender=YourModel) 

Ale nie jestem pewien, dlaczego nie można po prostu zastąpić metodę, która save jest prawie zawsze lepszym podejściem.

+0

+1 Dla wskazania, że ​​lepiej jest przesłonić metodę 'save()' w Modelu! – Caumons

9

Aby dostosować oszczędność inlines, można zastąpić formset

class SomeInlineFormSet(BaseInlineFormSet): 
    def save_new(self, form, commit=True): 
     return super(SomeInlineFormSet, self).save_new(form, commit=commit) 

    def save_existing(self, form, instance, commit=True): 
     return form.save(commit=commit) 

class SomeInline(admin.StackedInline): 
    formset = SomeInlineFormSet 
    # .... 

Należy pamiętać, że save_new() używa tylko formularz, aby uzyskać dane, nie pozwól ModelForm popełnić dane. Zamiast tego konstruuje sam model. Pozwala to wstawić relację macierzystą, ponieważ nie istnieją one w formularzu. Właśnie dlatego nadpisywanie form.save() nie działa.

W przypadku inlines generycznych, metoda form.save() nigdy nie jest wywoływana i form.cleaned_data jest używany zamiast uzyskać wszystkie wartości, a Field.save_form_data() służy do przechowywania wartości w instancji modelu.


FYI, ogólna wskazówka, aby dowiedzieć się tego rodzaju rzeczy; Naprawdę warto mieć IDE (lub może konfigurację vim lub Sublime), która pozwala na łatwe przejście do definicji symboli. Powyższy kod został opracowany przez wskoczenie do kodu linii/formularza i zobacz, co się dzieje. W przypadku PyCharm działa to przytrzymując Command (lub Ctrl) i klikając na symbol. Jeśli jesteś użytkownikiem vim, ctags może być w stanie zrobić coś podobnego.