[Answered ]-Get user OneToOneField fields in ModelForms

2👍

  • One option is to use inline formsets. Using this, you won’t be needing a second ModelForm.

    Inline formsets is a small abstraction layer on top of model formsets. These simplify the case of working with related objects via a foreign key.

    You can find good examples here.

  • Alternatively, if you want to avoid inline formsets and use both ProfileForm and AddressForm under a single <form> tag as you have done in your template, you can do it like this.

    Forms:

    class ProfileForm(ModelForm):
        class Meta:
            model = User
            fields = ('username', 'first_name', 'last_name', 'email')
    
    class AddressForm(ModelForm):
        class Meta:
            model = SiteUser
            exclude = ['user']
    

    Views:

    def edit_profile(request):
        username = request.user
        user = User.objects.get(username__exact=username)
        profileform_class = ProfileForm
        addressform_class = AddressForm
    
        if request.method == 'POST':
            profileform = profileform_class(data=request.POST, instance=user)
            addressform = addressform_class(data=request.POST, instance=user.siteuser)
            if all((profileform.is_valid(), addressform.is_valid())):
                user = profileform.save()
                address = addressform.save(commit=False)
                address.user = user
                address.save()
                return redirect('profile')
        else:
            profileform = profileform_class(instance=user)
            addressform = addressform_class(instance=user.siteuser)
    
        return render(request, 'edit_profile.html', {
            'user': user,
            'profileform': profileform,
            'addressform': addressform,
        })
    

0👍

I don’t know much about forms, but I think you should use the “initial” parameter when instantiating the AddressForm, as exemplified here: https://docs.djangoproject.com/es/1.9/topics/forms/modelforms/#providing-initial-values

So you create your AddressForm class with SiteUser as model, and when you instantiate it in the view, you make it like this:

AddressForm(initial={'user': request.user})

If “username” is not the primary key of the User model, you can get the primary key like this:

User.objects.get(username=request.user).pk

and then give it in the “initial” parameter.

0👍

model:

class Company(models.Model):
    name = models.CharField(max_length=150)
    description = models.CharField(max_length=150)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)


class Bike(models.Model):
    to_company = models.OneToOneField(Company, on_delete=models.CASCADE, related_name="bike_company")
    name_bike = models.CharField(max_length=150)
    model = models.CharField(max_length=150)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

form.py

class CompanyForm(ModelForm):
    class Meta:
        model = Company
        fields = ("name", "description" )


class BikeForm(ModelForm):
    name_bike = forms.CharField(required=True)
    model = forms.CharField(required=True)

    class Meta(CompanyForm.Meta):
        model = Company

    @transaction.atomic
    def save(self):
        company = super().save(commit=False)
        company.name = self.cleaned_data.get("name")
        company.description = self.cleaned_data.get("description")
        company.save()
        bike = Bike.objects.create(to_company=company)
        bike.name_bike = self.cleaned_data.get("name_bike")
        bike.model = self.cleaned_data.get("model")
        bike.save()
        return company

the relationship is kept in this line:

Bike.objects.create(to_company=company)

here is an example of a different type of user model

models user and type
https://gist.github.com/josuedjh3/259b4b3b03ab195637fe2db3c701edd6

FormModel the User and UserCreationForm

https://gist.github.com/josuedjh3/0c26d989552a82d5b252c5bd3fed1054

👤josue

Leave a comment