2

How can I pass the value of a variable to the value attribute of a field in my form? I have tried overriding the init method but I can't get it to work. This is my code.

models.py:

class Profile(models.Model):
    user = models.OneToOneField(UserManegement, related_name='user', on_delete=models.CASCADE)
    avatar = models.ImageField(upload_to=custom_upload_to, null=True, blank=True)
    first_name = models.TextField(user, null=True, blank=True)
    last_name = models.TextField(user, null=True, blank=True)
    phone = models.TextField(user, null=True, blank=True)

forms.py:

class ProfileForm(forms.ModelForm):

    class Meta:
        model = Profile
        fields = ['avatar', 'first_name','last_name', 'phone']
        widgets = {
            'avatar': forms.ClearableFileInput(attrs={'class': 'form-control-file mt-3'}),
            'first_name': forms.TextInput(attrs={'class': 'form-control mt-3', 'placeholder': 'Nombre'}),
            'last_name': forms.TextInput(attrs={'class': 'form-control mt-3', 'placeholder': 'Apellidos'}),
            'phone': forms.TextInput(attrs={'class': 'form-control mt-3', 'placeholder':'Teléfono'}),
        }

views.py:

@method_decorator(login_required, name='dispatch')
class ProfileUpdate(UpdateView):
    form_class = ProfileForm
    success_url = reverse_lazy('profile')
    template_name = 'registration/profile_form.html'

    def get_object(self):
        #recuperamos el objeto para editarlo
        profile, created =  Profile.objects.get_or_create(user=self.request.user)
        
        return profile

In this case, I would like to add the first time the form is loaded, the first_name field with the value of request.user.first_name.

Thank you very much!

1
  • 2
    Share the view where you use the form... Commented Apr 11, 2021 at 11:15

1 Answer 1

2

You can override the .get_initial(…) method [Django-doc] to provide intial values for a form, but since here you pass an instance to the form, it will take the values of the instance. You thus can create a Profile with the username:

from django.contrib.auth.mixins import LoginRequiredMixin

class ProfileUpdate(LoginRequiredMixin, UpdateView):
    form_class = ProfileForm
    success_url = reverse_lazy('profile')
    template_name = 'registration/profile_form.html'

    def get_object(self):
        #recuperamos el objeto para editarlo
        return Profile.objects.get_or_create(
            user=self.request.user,
            defaults={'first_name': self.request.user.first_name}
        )[0]

I'm however not sure that creating an instance in the UpdateView is a good idea. A GET request is supposed to have no side effects, but here you create a Profile when you make a GET request to the page.

Furthermore you also duplicate data, since now both the User and the Profile carry a first_name attribute. It is thus possible that the first_name of the User and its related Profile is different, resulting in all sorts of inconsistencies.


Note: You can limit views to a class-based view to authenticated users with the LoginRequiredMixin mixin [Django-doc].

Sign up to request clarification or add additional context in comments.

5 Comments

I have tried what you have posted. Then in form.py, inside the field I want the value to appear, I have to put this: 'first_name': forms.TextInput(attrs={'class': 'form-control mt-3', 'placeholder': 'Name'}, initial='first_name'), where what I'm including is initial?
@vien2: but it will not use the initial, since this is an UpdateView, it will pass the instance passed to the form, and use that value. initial is only given you create a new instance in the form.
I have entered that line, but it does not change anything. The first_name of the user still does not appear the first time the view is loaded. Any idea why this is happening?
@vien2: because you already created a Profile for that user before you changed the line?
That was it, I had a bug in the code. Thank you very much for your help!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.