Closed kunambi closed 11 months ago
I tried creating the field through
modelfield = getattr(self._meta.model, f"{addable.get('name')}_{default_lang}")
translated_field = create_translation_field(
model=self._meta.model,
field_name=addable.get("name"),
lang=lang,
empty_value=None if modelfield.field and modelfield.field.null else "",
)
formfield = translated_field.formfield()
But with the same erroneous result
Try looking into form.save to understand why field isnt' saved.
form.save()
is called on the django.forms.models.BaseModelForm
, which only calls self.instance.save()
(if no errors are found).
No errors are encountered, but the data of the instance isn't updated.
What am I missing?
Look at what's happening before that. I think it's BaseModelForm._post_clean
method.
Check if all fields are available in cleaned_data.
But before we get too far, try using modelform_factory instead of adding fields in __init__
. Maybe it will just work.
Look at what's happening before that. I think it's BaseModelForm._post_clean method. Check if all fields are available in cleaned_data.
As I showed in the first post, the cleaned_data
does indeed contain the value for description_es
. The problem is that it doesn't seem to be saved.
But before we get too far, try using modelform_factory instead of adding fields in
__init__
. Maybe it will just work.
modelform_factory
is not what I want to use in this scenario. I have other uses of it in other locations. Why do you think it will work?
It seems like there's some kind of magic happening when form.save()
is run. django-modeltranslation
is supposedly patching how the models are saved, hopefully I'll understand the source code
I managed to find a solution. The problem was with django.forms.models.BaseModelForm
which removes any fields which aren't defined in Meta.fields
through the use of object_data = model_to_dict(instance, opts.fields, opts.exclude)
.
Solution became:
# ...
for addable in to_add:
for lang in addable.get("languages"):
field_name = f"{addable.get('name')}_{lang}" # "description_es"
formfield = addable.get("formfield")
formfield.label = formfield.label.replace(f"[{default_lang}]", f"[{lang}]")
formfield.required = False
formfield.initial = getattr(self.instance, field_name, "")
self.fields[field_name] = formfield
self.field_order.insert(addable.get("position", 0) + 1, field_name)
# these lines made the difference
if field_name not in self._meta.fields:
self._meta.fields = self._meta.fields + (field_name,)
self.order_fields(self.field_order)
I'm attempting to dynamically add translatable fields for my
forms.ModelForm
, depending on whether the customer has enabled the language or not. However, the translated value isn't saved to the model.This code allows me to render the fields accordingly. If the customer has selected to show e.g.
"es"
(Spanish), the translatable field ("description_en"
) will be copied and I create a new field ("description_es"
) in the right position inside thefield_order
. So far, all is well.But when I POST the form, this is what happens inside my view:
Here is what I don't understand: why isn't the
description_es
value saved to the object?