Access parent object fields of save_formset and save_model
-
13-06-2021 - |
Вопрос
I have a ActionAdmin model, which is used as ActionAdminInline in the InvoiceAdmin model.
In InvoiceModel i override save_formset, to auto set some values. Setting the values for each Action instance is no problem, but i could not get the fields of the parent Invoice.
I thought it had to be self or self.project.pk I also tried to get it by form.project.pk seen in some other thread.
The errors i get, are about no such Field in InvoiceAdmin. That makes sense to me, self is an InvoiceAdmin object and not an Invoice object. I think i had to get the Invoice object fields to set Action instance.invoice and instance.project.
Does somebody know, how to get this parent object values ???
looks like this:
class ActionAdmin(admin.ModelAdmin):
...
class ActionInlineForm(ModelForm):
class Meta:
model = Action
fields = ['name','tax', 'price','duration_extern',]
class ActionInline(admin.TabularInline):
model = Action
form = ActionInlineForm
extra = 0
ordering = ('date_finished',)
can_delete=False
readonly_fields = ['non_editable_date_finished','non_editable_duration','get_remove_invoice_pos_link']
class InvoiceAdmin(admin.ModelAdmin):
...
...
...
inlines = [ActionInline,]
...
...
...
def save_formset(self, request, form, formset, change):
instances = formset.save(commit=False)
for instance in instances:
usr = User.objects.get(id=7)
try:
instance.created_by = instance.created_by
except:
instance.created_by = usr
try:
instance.owner = instance.owner
except:
instance.owner = usr
instance.modified_by = usr
try:
instance.date_created = instance.date_created
except:
instance.date_created = date.today
instance.date_modified = date.today:
### MAN, This WORKS NOW ###
try:
instance.project = instance.project
except:
pr = Project.objects.get(id=instance.invoice.project.id)
instance.project = pr
actstat = ActionStatus.objects.get(id=2)
instance.actionstatus = actstat
try:
instance.actioncategory = instance.actioncategory
except:
cat = ActionCategory.objects.get(id=9)
instance.actioncategory = cat
instance.done = True
instance.billed = True
instance.save()
formset.save_m2m()
This is the error message:
AttributeError at /workflow/invoice/21/
...
Exception Type: AttributeError
Exception Value: 'InvoiceAdmin' object has no attribute 'id'
...
Traceback
form <django.forms.models.InvoiceForm object at 0x7f7f7421de10>
instances [<Action: aaaaa>]
self <workflow.admin.InvoiceAdmin object at 0x7f7f7421dad0>
Is it the problem, that the self object is InvoiveAdmin and not Invoice? I mean the instances objects are Action and not ActionAdmin?!
Решение
OK. i found a solution for instance.invoice. It's correctly set without doing anything for instance.invoice. I removed the line "instance.invoice = self" from the code above.
The solution to get the project by parent object, which is an invoice is done by "instance.invoice.project.id"
So i traverse form action to invoice to project an than to it's id. Changed this also above.
And it's nescessary to check instance fields with try,except. First i tried
if not instance.project
and
if not hasatrr(instance,'project')
or
if instance.project=""
But without exception handling it raises an DoesNotExists error. Changed it from if/else to try/except above.
BTW
Realy rare. I'm just changing something in ActionAdmin save_model
When i try to proove instance field there, the same way with try/except like in save_formset, i don't works.
In save_model i had to do:
if not instance.price:
instance.price = instance.project.customer.price
this fails
try:
instance.price = instance.price
except:
instance.price = instance.project.customer.price
And in save_formset it's viceversa ??? !
Somebody could explain that to me?