Multiple form in one page with Foreign Key

Hello!
I want to build Edit Profile from different models.
I think it will be kind of major models Profile with Foreign Key in different models. I can have build view which post data excellent but when user reopen edit profile page fields doesn’t show content.
For example, Models have fields about University (name, position etc.). I open a page when to want to update information about me. I write name my university. Fields saves good. But when I reopen this forms, I don’t see name my university.
I have been trying to create it with Class-Based View, but it worked not good. So now I’m trying to create it with Function-Based View.
models.py

class Profile(models.Model):
    slug = models.SlugField(unique=True)
    user = models.OneToOneField(get_user_model(), on_delete=models.CASCADE)
    bio = RichTextField(null=False, blank=True)
    university = models.ForeignKey(
        'University', on_delete=models.CASCADE, blank=True, null=True)
    work = models.ForeignKey(
        'Work_place', on_delete=models.CASCADE, blank=True, null=True)

      def __str__(self):
        return f"{self.user.username} Profile"

    def get_absolute_url(self):
        return reverse("profile", args=[self.slug])

class University(models.Model):
    slug = models.SlugField(unique=True)
    name = models.CharField(max_length=250)
    position = models.CharField(max_length=255, blank=True, null=True)
    location = models.ForeignKey(
        'Location', on_delete=models.CASCADE, blank=True, null=True)
    start_date = models.DateTimeField(
        default=timezone.now, blank=True, null=True)
    end_date = models.DateTimeField(
        default=timezone.now, blank=True, null=True)

class Work_place(models.Model):
    name = models.CharField(max_length=250)
    position = models.CharField(max_length=255, blank=True, null=True)
    location = models.ForeignKey(
        'Location', on_delete=models.CASCADE, blank=True, null=True)
    start_date = models.DateTimeField(
        default=timezone.now, blank=True, null=True)
    end_date = models.DateTimeField(
        default=timezone.now, blank=True, null=True)

    def __str__(self):
        return str(self.name)

    class Meta:
        ordering = ["-name"]

views.py


def update_profile(request, slug):
    if request.method == "POST":
        user_form = UserForm(
            request.POST, instance=request.user, prefix="user")
        profile_form = ProfileForm(
            request.POST, request.FILES, instance=request.user.profile, prefix="profile")
        work_form = WorkForm(request.POST, prefix="profile_form")
        university_form = UniversityForm(request.POST, prefix="university")
        if all([user_form.is_valid() and work_form.is_valid() and profile_form.is_valid() and university_form.is_valid()]):
            us = user_form.save()
            prof = profile_form.save()
            wor = work_form.save()
            uni = university_form.save()

            prof.university = uni
            prof.work = wor
            prof.save()

            messages.success(request, _(
                "Your profile was successfully updated!"))
            return redirect("profile", slug=slug)
        else:
            messages.error(request, _("Please correct the error below."))
    else:
        user_form = UserForm(instance=request.user, prefix="user")
        profile_form = ProfileForm(instance=request.user.profile)
        work_form = WorkForm(prefix="profile")
        university_form = UniversityForm(prefix="university")
    return render(
        request,
        "users/profile_update.html",
        {"user_form": user_form, "profile_form": profile_form,
            "work_form": work_form, "university_form": university_form, },
    )

forms.py

class UserForm(forms.ModelForm):
    class Meta:
        model = CustomUser
        fields = (
            "username",
            "first_name",
            "last_name",
            "email",
            "gender",
        )

class UniversityForm(forms.ModelForm):
    class Meta:
        model = University
        fields = (
            "name",
            "description",
        )
class ProfileForm(forms.ModelForm):
    class Meta:
        model = Profile
        fields = ("bio",)

In the GET portion of your view, you’re not specifying which instance of Work_place and University to use as the Model instance in the form.

Ken, thank you!
But I don’t how to be better build it. Could you give me an advice?

Notice how for the user_form and the profile_form, you’re using the instance parameter to identify which User and Profile objects you’re working with on the form.
You want to do the same thing for WorkForm and UniversityForm. (With the right instances of the appropriate objects.)

I tried to build a something like

    university_form = UniversityForm( instance=request.university.profile, prefix="university")  #ver. 1
    university_form = UniversityForm( instance=request.university, prefix="university")        # ver. 2

But it doesn’t work.

Ok, let’s break this down a little.

Forget the forms for a moment. Look at this in more general terms. How would locate a University object associated with you? (What in your data identifies a specific instance of University with any one individual?)

Each user has a profile. So, each user and profile has a University. Right?

I don’t know - it’s your data. Does a User have a University or does a Profile have a University? Or both?

Profile has a University and Work.

Ok, so you need to access the University through the Profile object.

Given a Profile, how do you access the University object associated with that Profile?

Then, back to your view, how do you access the Profile object?

Finally, how might you combine the previous two answers to get the University object for a Profile in your View?

1 Like

Ken, thank you so much! You always help me a lot.

        work_form = WorkForm(
            prefix="profile", instance=request.user.profile.work)
        university_form = UniversityForm(
            instance=request.user.profile.university, prefix="university")

Can you tell me, I need to use “prefix”?

Since you have multiple forms on the same page in the same form tag with the same field name, yes.
Even if you were in a situation where it wasn’t strictly necessary, it never hurts to supply it.

Thank you again, Ken!
I appreciate you helping me and wasting your time!