The expected Django behavior (filling the form with the passed instance data) didn’t work in this case, here is my code:
The UpdateView:
class ClientProfile(LoginRequiredMixin, UpdateView):
model = get_user_model()
form_class = ProfileForm
template_name = 'client_profile.html'
# def get_initial(self):
# initial = super().get_initial()
# for field_name in self.object._meta.get_fields():
# if hasattr(self.object, field_name.name):
# initial[field_name.name] = getattr(self.object, field_name.name)
# return initial
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
kwargs['profile_includes_instance'] = self.object.profile_includes
return kwargs
It works only when using the get_initial method. However, I know from the documentation that passing the instance (automatically done with UpdateView) will prefill the rendered form perfectly.
The ModelForm:
class ProfileForm(forms.ModelForm):
profile_includes_form = ProfileIncludesForm()
# include the profile_include form
def __init__(self, *args, **kwargs):
# to get previous data if exist else None
profile_includes_instance = kwargs.pop('profile_includes_instance', None)
super().__init__(*args, **kwargs)
self.profile_includes_form = ProfileIncludesForm(
*args,
instance=profile_includes_instance,
)
def is_valid(self):
return super().is_valid() and self.profile_includes_form.is_valid()
def save(self, commit=True):
client = super().save(commit=commit)
profile_includes_form = self.profile_includes_form.save(commit=False)
profile_includes_form.client = client
if commit:
profile_includes_form.save()
return client
class Meta:
# ...
I appreciate every help you provide, thank you in advance
Side note: Something here that may or may not be directly relevent to this specific issue, is that whenever you’re handing data from multiple forms on the same page, you want to use the prefix attribute on the form to ensure the post data is directed to the right form instance.
Fields of the user model? That’s the only way they’re going to be applied to this form.
If you want additional fields on the form that aren’t part of the model, they need to be defined on the form. (ModelForms only generate fields for the fields in the model, and the widgets dict in Meta only apply to those generated fields.)
@KenWhitesell
Regarding the fields, I changed the main user model from User to my custom Client model, and yes you’re right, I did define the profile_includes_form = ProfileIncludesForm() at the top of the ModelForm (is that what you mean?), however, my main issue here is that the main ModelFom (ProfileForm) didn’t prefill the existing data of the self.object, and I don’t know why. any help would be appreciated sir, thank you so much
Is create a class-variable containing a blank instance of the form. This isn’t going to work the way you’re thinking it’s going to work.
A form is not a field.
The light has gone on - now I think I understand what you’re trying to do.
Unfortunately, my response to this is “don’t do this”. Work with the two forms as two separate forms - do not try to integrate them like this. (This is an approach that I wouldn’t ever try to do.)
There’s a lot of “metaprogramming magic” that occurs within the Django Form class, and even more with ModelForms.
I have a philosophy that has served me well for a long time: “Don’t fight the framework.” Do things the way the framework expects you to do them, don’t try to twist it to make it fit your mental model - change your mental model instead.