vien2
vien2

Reputation: 23

Pass variable value to form field

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!

Upvotes: 2

Views: 251

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 477641

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].

Upvotes: 2

Related Questions