Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Override a Django generic class-based view widget

Tags:

django

Say I have a basic CreateView form, like this, to allow new users to register on a site:

from django.contrib.auth import get_user_model from django.http import HttpResponse from django.views.generic import CreateView  User = get_user_model()   class Signup(CreateView):      model = User     fields = ['first_name', 'last_name', 'email', 'password'] 

I just tried this, and found that the password field is rendered in plain text; how would I go about overriding the view so that it uses forms.PasswordInput() instead? (I realise it's probably easiest to just define the form by hand, but I'm just curious about how you'd do that.)

like image 699
david_hughes Avatar asked Dec 05 '14 17:12

david_hughes


People also ask

What does CreateView do in Django?

CreateView. A view that displays a form for creating an object, redisplaying the form with validation errors (if there are any) and saving the object. This view inherits methods and attributes from the following views: django.

What is Form_valid in Django?

Model form views provide a form_valid() implementation that saves the model automatically. You can override this if you have any special requirements; see below for examples. You don't even need to provide a success_url for CreateView or UpdateView - they will use get_absolute_url() on the model object if available.

What is Django FormView?

FormView refers to a view (logic) to display and verify a Django Form. For example, a form to register users at Geeksforgeeks. Class-based views provide an alternative way to implement views as Python objects instead of functions.

How do you write class-based views in Django?

Asynchronous class-based viewsimport asyncio from django. http import HttpResponse from django. views import View class AsyncView(View): async def get(self, request, *args, **kwargs): # Perform io-blocking view logic using await, sleep for example. await asyncio.


2 Answers

You could override get_form(), and modify the form to change the widget on the password field:

from django import forms  class Signup(CreateView):     model = User     fields = ['first_name', 'last_name', 'email', 'password']      def get_form(self, form_class):         form = super(Signup, self).get_form(form_class)         form.fields['password'].widget = forms.PasswordInput()         return form 

But an even better way would be to just create a custom form class. In the custom class just set widgets on the Meta class. Like this:

from django import forms  class SignupForm(forms.ModelForm):     class Meta:         model = User         fields = ['first_name', 'last_name', 'email', 'password']         widgets = {             'password': forms.PasswordInput()         }  class Signup(CreateView):     form_class = SignupForm     model = User 

Usually you would put the custom form class in a forms.py file as well.

like image 96
jproffitt Avatar answered Sep 21 '22 04:09

jproffitt


Not sure if this affected earlier versions of Django, but in more recent versions the get_form() should have a default form_class=None when overriding that method.

The updated (Python 3, Django 2.2) example would be:

from django import forms  class Signup(CreateView):     model = User     fields = ['first_name', 'last_name', 'email', 'password']      def get_form(self, form_class=None):         form = super().get_form(form_class)         form.fields['password'].widget = forms.PasswordInput()         return form 

https://docs.djangoproject.com/en/2.2/ref/class-based-views/mixins-editing/#django.views.generic.edit.FormMixin

like image 29
kbuilds Avatar answered Sep 19 '22 04:09

kbuilds