I'm using UserCreationForm in Django and I'm trying add help_text to the email field.
Here's the forms.py code:
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import UserCreationForm, UserChangeForm
class CustomUserCreationForm(UserCreationForm):
class Meta(UserCreationForm):
model = get_user_model()
fields = ('email','username',)
help_texts = {
'email': 'Use your work email',
}
I'm using Crispy Forms to render it and it isn't rendering the help_text.
As another approach, I tried adding this to the class:
def __init__(self, *args, **kwargs):
super(CustomUserCreationForm, self).__init__(*args, **kwargs)
self.fields['email'].help_text = 'hello'
But it didn't work either.
What am I missing?
EDIT: I realised I made a mistake with this question. This project had switched to using django-allauth, but left forms.py in the user app of this django project. Therefore none of the changes in these forms were having any effect. A check of the settings would've shown that it was using allauth.
help_texts is not an attribute of the Meta class of a form. You can add the help text for the email field in your model, like this:
email = models.EmailField(max_length=200, help_text='use your work email', blank=True, null=True)
Since email is not one of the fields of UserCreationForm (see https://docs.djangoproject.com/en/3.0/topics/auth/default/#django.contrib.auth.forms.UserCreationForm), setting the field via init will not work.
Related
I've been learning Django and I'm trying to understand how to extend some of the built-in functionality. To do that I've referenced Customizing Authentication in Django and tried to implement the instructions I've found there in a standard django-admin project.
The problem is that when I try to save the form to the database (sqlite3 included db), nothing is recorded. The form passes the is_valid check, but when I check the database however, nothing has been added to either my user or patients tables.
Hoping someone can point out where this is going wrong, thank you.
models.py
from django.db import models
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
isPatient = models.BooleanField(default=False)
class Patient(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
age = models.PositiveIntegerField()
forms.py
from django import forms
from django.contrib.auth.forms import UserCreationForm
from django.db import transaction
from .models import *
class RegisterPatient(UserCreationForm):
age = forms.IntegerField()
class Meta:
model = User
fields = UserCreationForm.Meta.fields + ("age")
#transaction.atomic
def save(self, commit=True):
user = super(RegisterPatient, self).save(commit=False)
user.isPatient = True
user.save()
patient = Patient.objects.create(user=user)
patient.firstName.add(*self.cleaned_data.get('age'))
patient.save()
views.py
def register(response):
form = RegisterPatient(response.POST)
if form.is_valid():
print("is Valid") # < Code reaches here
form.save
return redirect("/")
settings.py
AUTH_USER_MODEL = 'main.User'
admin.py
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from . models import User
admin.site.register(User, UserAdmin)
You need to replace form.save with form.save(). The latter calls the save function, whereas the former does not.
I'm making a user login form with a CustomUser model derived from AbstractUser, with one extra field: date_of_birth. I use CreateView to generate the form. All fields show up, the password field uses the password widget as expected (showing dots instead of characters), but the date field does not (plain character field with no formatting or calendar). What am I overlooking?
models.py:
from django.urls import reverse
from django.contrib.auth.models import AbstractUser
# Create your models here.
class CustomUser(AbstractUser):
date_of_birth = models.DateField(verbose_name="Date of Birth", blank=True, null=True)
def get_absolute_url(self):
return reverse('index')
def __str__(self):
return self.username
forms.py:
from .models import CustomUser
class CustomUserForm(forms.ModelForm):
class Meta:
model = CustomUser
fields = ["username", "password", "first_name", "last_name", "email", "date_of_birth"]
widgets = {
"password": forms.PasswordInput(),
"date_of_birth": forms.DateInput()
}
views.py:
from django.views.generic.edit import CreateView
from .models import CustomUser
from .forms import CustomUserForm
# Create your views here.
def index(request):
return HttpResponse("Hello, world")
class CustomUserCreate(CreateView):
model = CustomUser
form_class = CustomUserForm
If you come here in 2020 and beyond, just overide the default type=text undelying input by using 'type':'date'
So something like the below would work. Tested on Mozilla Dev Edition 73.+
'date_of_birth': forms.DateInput(attrs={'class':'form-control', 'type':'date'}),
Django has no built-in fancy datepicker. DateField uses the DateInput widget which is just a text input.
Thanks voodoo-burger for pointing me in the right direction. I found a video with a very simple solution to use the HTML5 datepicker: https://www.youtube.com/watch?v=I2-JYxnSiB0.
It only requires to add the following to forms.py:
class DateInput(forms.DateInput):
input_type = 'date'
and then use this as the widget (so replace forms.DateInput() with DateInput()).
I am new to Django and I have been trying this for weeks, but could not find a way to solve this problem.
I want to store additional information like user mobile number, bank name, bank account. And want to store the mobile number while user registers and wants user to login with either (mobile number and password) or (email and password).
This is my UserProfile model
from django.db import models
from django.contrib.auth.models import User
from django.contrib.auth.models import AbstractUser
# Create your models here.
class UserProfile(AbstractUser):
user_mobile = models.IntegerField(max_length=10, null=True)
user_bank_name=models.CharField(max_length=100,null=True)
user_bank_account_number=models.CharField(max_length=50, null=True)
user_bank_ifsc_code = models.CharField(max_length=30,null=True)
user_byt_balance = models.IntegerField(max_length=20, null=True)
And this is my forms.py
from django import forms
from django.contrib.auth.models import User # fill in custom user info then save it
from django.contrib.auth.forms import UserCreationForm
from models import UserProfile
from django.contrib.auth import get_user_model
class MyRegistrationForm(UserCreationForm):
email = forms.EmailField(required = True)
mobile = forms.IntegerField(required=True)
class Meta:
model = UserProfile
fields = ('username', 'email', 'password1', 'password2','mobile' )
def save(self,commit = False):
user = super(MyRegistrationForm, self).save(commit = False)
user.email = self.cleaned_data['email']
user.user_mobile = self.cleaned_data['mobile']
user.set_password(self.cleaned_data["password1"])
user_default = User.objects.create_user(self.cleaned_data['username'],
self.cleaned_data['email'],
self.cleaned_data['password1'])
user_default.save()
if commit:
user.save()
return user
In my settings.py I have included
AUTH_USER_MODEL = "registration.UserProfile"
admin.py of my app is
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from models import UserProfile
class UserProfileInline(admin.StackedInline):
model = UserProfile
can_delete = False
verbose_name_plural = 'userprofile'
class UserProfileAdmin(UserAdmin):
inlines = (UserProfileInline, )
admin.site.register(UserProfile, UserProfileAdmin)
While adding the user from admin I get this error
Exception at /admin/registration/userprofile/1/
<class 'registration.models.UserProfile'> has no ForeignKey to <class 'registration.models.UserProfile'>
Can someone help me with this or point out to the full working exapmle, I have seen Django documentation but didn't find any luck. Or if there is another way to do this.
Thanks in advance
Edit 1:
While registering from the registration form I'm also getting this error
DatabaseError at /register
(1146, "Table 'django_auth_db.auth_user' doesn't exist")
You have confused yourself a bit here. The idea of subclassing AbstractUser - and defining AUTH_USER_MODEL as your subclass - is that the new model completely replaces auth.models.User. You shouldn't be importing the original User at all, and you certainly should be calling User.objects.create_user(): your new model's manager now has its own create_user method.
Because of this, there's no reason to muck about with inline admins. Your UserProfile should be registered in the admin using the existing django.contrib.auth.admin.UserAdmin class.
Inlines forms assume that you have a Generic ForeignKey on your model, in this case, the UserProfileAdmin expect a Generic ForeignKey of the UserProfile, that does not exists. Try to do a regular Model Admin, like:
class UserProfileAdmin(admin.ModelAdmin):
can_delete = False
verbose_name_plural = 'userprofile'
admin.site.register(UserProfile, UserProfileAdmin)
I found this post on how to extend the UserCreationForm with extra fields such as "email." However, the email field is already defined in the pre-built user model.
I created an extra model (called UserProfile) that futher extends Django's pre-built User class. How do I get these fields I defined in UserProfile to appear in my UserCreationForm?
Add fields as appropriate for your UserProfile model (it's not too easy to use a ModelForm to avoid Repeating Yourself, unfortunately), then create and save a new UserProfile instance in the over-ridden save() function. Adapted from the post you linked to:
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserCreateForm(UserCreationForm):
job_title = forms.CharField(max_length=100, required=True)
age = forms.IntegerField(required=True)
class Meta:
model = User
def save(self, commit=True):
if not commit:
raise NotImplementedError("Can't create User and UserProfile without database save")
user = super(UserCreateForm, self).save(commit=True)
user_profile = UserProfile(user=user, job_title=self.cleaned_data['job_title'],
age=self.cleaned_data['age'])
user_profile.save()
return user, user_profile
I need to make the email field in the Django User model mandatory. It isn't obvious to me how to do that. Suggestions welcome. I am currently using:
from django.contrib.auth.forms import UserCreationForm
for my User creation form, and combining this with my own custom UserProfileCreateForm
Ian
You should be able subclass the provided registration form and override properties of a field in the Meta class.
from django.contrib.auth.forms import UserCreationForm
# Not sure about the syntax on this one. Can't find the documentation.
class MyUserCreationForm(UserCreationForm):
class Meta:
email = {
'required': True
}
# This will definitely work
class MyUserCreationForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(MyUserCreationForm, self).__init__(*args, **kwargs)
self.fields['email'].required = True
from django import forms
from django.contrib.auth.models import User
class MyUserForm(forms.ModelForm):
email = forms.CharField(max_length=75, required=True)
class Meta:
model = User
fields = ('username', 'email', 'password')
use EmailField in your model
see more at
https://docs.djangoproject.com/en/2.1/ref/models/fields/#emailfield