0

I'm working with a django(4) project, Where I have two forms and want to combine them into one to display in my template with custom html not by sing {{form}} syntax.

Here's my forms.py:

class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'email']

# Create a ProfileUpdateForm to update image.
class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']

How can I combine both of these forms into single one to display all the filed in HTML and submit as a single form?

Abdul Rehman
  • 5,326
  • 9
  • 77
  • 150

2 Answers2

0

you can use html form tag without sumbit button. and save new data with javascript function by ajax.

MortexaFarhadi
  • 87
  • 1
  • 1
  • 13
0

You can try creating one form that is a combination of those 2 forms, and then display that as usual.

So for the form, something like this (implemented into your forms.py):

from django import forms
from django.contrib.auth.models import User
from .models import Profile

class UserUpdateForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'email']


class ProfileUpdateForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ['image']


class CombinedForm(forms.ModelForm):
    email = forms.EmailField()

    class Meta:
        model = User
        fields = ['username', 'first_name', 'last_name', 'email', 'image']

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields.update(ProfileUpdateForm(*args, **kwargs).fields)

Now, your template would look something like this:

<form method="post" enctype="multipart/form-data">
  {% csrf_token %}
  <label for="{{ form.username.id_for_label }}">Username:</label>
  {{ form.username }}
  <br>
  <label for="{{ form.first_name.id_for_label }}">First name:</label>
  {{ form.first_name }}
  <br>
  <label for="{{ form.last_name.id_for_label }}">Last name:</label>
  {{ form.last_name }}
  <br>
  <label for="{{ form.email.id_for_label }}">Email:</label>
  {{ form.email }}
  <br>
  <label for="{{ form.image.id_for_label }}">Image:</label>
  {{ form.image }}
  <br>
  <input type="submit" value="Update">
</form>

Then your views.py would process it like any normal form:

def profile_update(request):
    if request.method == 'POST':
        form = CombinedForm(request.POST, request.FILES, instance=request.user)
        if form.is_valid():
            form.save()
            messages.success(request, 'Your profile has been updated!')
            return redirect('profile')
    else:
        form = CombinedForm(instance=request.user)
    context = {'form': form}
    return render(request, 'profile_update.html', context)

This should help, unless there is a specific reason you want to keep your form as 2 separate forms - in which case either way, you could store the information as you please, so I don't see why it would be an issue.

Kovy Jacob
  • 489
  • 2
  • 16
  • Best of luck! I would post that in the answer, but last time I tried it someone got mad at me. And good luck with the most epic framework ever! – Kovy Jacob Apr 02 '23 at 08:12