Custom fields in user model Django - python

I am using normal User model in Django to save my users. I would like to add first_name and last_name field, but I don't know how to extend my model and make it work. First and last name should be added in in register form (I use crispy forms).
register view
if request.method == "POST":
form = UserRegisterForm(request.POST)
if form.is_valid():
form.save() # save user to database
username = form.cleaned_data.get('username')
messages.success(request, f"User {username} succesfully created! You can login now!")
return redirect('login')
else:
form = UserRegisterForm()
return render(request, 'users/register.html', {'form': form})
register form
def __init__(self, *args, **kwargs):
super(UserRegisterForm, self).__init__(*args, **kwargs)
self.fields['password1'].label = "Hasło"
self.fields['password2'].label = "Powtórz hasło"
email = forms.EmailField()
name = forms.CharField(
label="Imię",
required=True,
max_length=30,
)
surname = forms.CharField(
label="Nazwisko",
required=True,
max_length=30,
)
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2', 'name', 'surname']
labels = {
'username': 'Nazwa użytkownika',
}

Django's User model [Django-doc] already has a first_name and last_name, you can subclass the UserCreationForm and add fields for the first_name and last_name:
from django.contrib.auth.forms import UserCreationForm
class UserRegisterForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(UserRegisterForm, self).__init__(*args, **kwargs)
self.fields['password1'].label = 'Hasło'
self.fields['password2'].label = 'Powtórz hasło'
email = forms.EmailField()
first_name = forms.CharField(
label='Imię',
required=True,
max_length=30,
)
last_name = forms.CharField(
label='Nazwisko',
required=True,
max_length=30,
)
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2', 'first_name', 'last_name']
labels = {
'username': 'Nazwa użytkownika',
}

Related

Django - How to run consecutive forms?

I have a user registration form that asks for user information and also asks a question: "Are you a PSMC member?"
The options are:
rank = [
('Supporter', 'Supporter (non-member)'),
('Anak', 'Anak'),
('Uso', 'Uso'),
('Chief', 'Chief'),
]
If Supporter is selected, then the registration form proceeds and saves user info, etc. This part works fine. However, if Anak is selected, I want it to take the user to another form that asks additional questions.
In my forms.py, I have class RegisterForm which is the main registration form for all users. I also have class AnakRegisterForm which is what I want it to continue on to. I used Django's AuthenticationForm based off what I read from their website (but I could be wrong). I know the issue is in views.py register function. Specifically:
if rank == 'Anak':
anak_register(response)
During my debug session, after it moves response to anak_register function, it gets a bunch of scrambled information. I'm pretty lost, any help would be appreciated. Here is my code:
forms.py
class RegisterForm(UserCreationForm):
email = forms.EmailField(
initial='',
required=True,
help_text='Please enter a valid email address'
)
rank = forms.ChoiceField(
label='Are you a PSMC member?',
choices=SavBlock.models.User.rank,
initial=False,
required=True,
help_text='Member accounts will be validated with your HC.'
)
class Meta:
model = User
# username = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
fields = ['username', 'first_name', 'last_name', 'email',
'rank', 'password1', 'password2']
def save(self, commit=True):
user = super(RegisterForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.ranking = self.cleaned_data['rank']
if commit:
user.save()
return user
class AnakRegisterForm(AuthenticationForm):
tribe = forms.ChoiceField(
label='What tribe are you from, Uce?',
choices=SavBlock.models.Anak.tribe,
initial=False,
required=True,
help_text='Member accounts will be validated with your HC.'
)
class Meta:
model = Anak
fields = ['tribe']
def save(self, commit=True):
user = super(AnakRegisterForm, self).save(commit=False)
user.tribe = self.cleaned_data['tribe']
if commit:
user.save()
return user
class UsoRegisterForm(AuthenticationForm):
pass
class ChiefRegisterForm(AuthenticationForm):
pass
views.py
def register(response):
context = {}
if response.method == "POST":
form = RegisterForm(response.POST)
if form.is_valid():
form.save()
rank = form.cleaned_data.get('rank')
if rank == 'Anak':
anak_register(response)
else:
form.save()
messages.success(response, 'Registration successful. Please login.')
return redirect('login')
else:
context['register'] = form
else:
form = RegisterForm()
context['register'] = form
return render(request=response, template_name='register/register.html', context={'form': form})
def anak_register(response):
# context = {}
if response.method == "POST":
form = AnakRegisterForm(response.POST)
if form.request.is_valid():
form.save()
messages.success(response, 'Registration successful. Please login.')
return redirect('login')
else:
'''
context['register'] = form
'''
else:
form = AnakRegisterForm()
# context['register'] = form
# messages.error(request, 'Unsuccessful registration. Invalid information.')
# form = RegisterForm
return render(request=response, template_name='register/register.html', context={'form': form})
models.py
class User(AbstractBaseUser, PermissionsMixin):
rank = [
('Supporter', 'Supporter (non-member)'),
('Anak', 'Anak'),
('Uso', 'Uso'),
('Chief', 'Chief'),
]
tribe = [
('NaKoaHema', 'Na Koa Hema'),
('Alakai', 'Alaka\'i')
]
username = models.CharField("user name", max_length=50, default='', unique=True)
email = models.EmailField("email address", max_length=30, unique=True, blank=True)
first_name = models.CharField("first name", max_length=50)
last_name = models.CharField("last name", max_length=50)
is_active = models.BooleanField('active', default=True)
# password = models.CharField("password", unique=True, max_length=32, default='')
id = models.AutoField(primary_key=True)
is_staff = models.BooleanField('staff status', default=False)
date_joined = models.DateField('date_joined', default=timezone.now)
ranking = models.CharField(choices=rank, max_length=50, default="Supporter")
objects = UserManager()
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['email', 'password', 'ranking']
# Magic method returns string of self
def __str__(self):
return f"User {self.first_name} {self.last_name} rank {self.rank}".strip()
#property
def get_full_name(self):
return f"{self.first_name} {self.last_name}".strip()
class Anak(User):
def __init__(self, first_name, last_name, tribe):
super().__init__(first_name, last_name)
self.tribe = tribe.title()
self.rank = User.rank[1]
EDIT
I changed AuthenticationForm to UserCreationForm and now it accepts the form. However, when I try to run it, I get the following error:
TypeError at /register/
__init__() missing 1 required positional argument: 'tribe'
If someone could point me in the right direction, I'd appreciate it!
Not sure how I missed this, but the best solution that I found is to implement Django Form Wizard. More information can be found here:
https://django-formtools.readthedocs.io/en/latest/wizard.html

Not able to create a SignUp page using Django

I am not able to create a User Registration page using Django where I have used a Profile model with the OnetoOne field with the default User model.
views.py
def SignUpView(request):
if request.method == 'POST':
user_form = SignUpForm(data=request.POST)
profile_form = ProfileForm(data=request.POST)
if user_form.is_valid() and profile_form.is_valid():
new_user = user_form.save(commit=False)
new_profile = profile_form.save(commit=False)
new_profile.user = new_user
userName = new_user.username
password = new_profile.password1
new_user.save(commit=True)
new_profile.save(commit=True)
user = authenticate(username = userName, password = password)
login(request, user)
return redirect('blog-home')
else:
user_form = SignUpForm()
profile_form = ProfileForm()
context = {
'user_form': user_form,
'profile_form': profile_form,
}
return render(request, 'user/signup.html', context=context)
forms.py:
class SignUpForm(UserCreationForm):
class meta:
model = User
fields = ['username', 'first_name', 'last_name', 'password1', 'password2']
class ProfileForm(forms.ModelForm):
class meta:
model = Profile
fields = ['user', 'email']
models.py:
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
# img =
date_of_birth = models.DateField(blank=True, null=True)
bio = models.CharField(blank=True, max_length=500)
location = models.CharField(blank=True, max_length=50)
email = models.EmailField(unique=True, max_length=200)
def __str__(self):
return f'Profile for {self.user.username}'
It is displaying an error message on the signup page as :
ValueError at /signup/
ModelForm has no model class specified.
It could be because there's a typo in your meta class declaration.
Change it to - class Meta. Note the case.
Did you try this to get the User model?
from django.contrib.auth import get_user_model
User = get_user_model()
Change it to - class Meta
class SignUpForm(UserCreationForm):
class Meta:
model = User
fields = ['username', 'first_name', 'last_name', 'password1', 'password2']
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['user', 'email']
If this isn't a form based on a model, don't inherit from forms.ModelForm, just use an ordinary forms.Form.

How to save IP of user after submitting the django custom form

I wrote my own form for editing of profile and need to save ip of user, who edit profile, but not really understand how to do this. I know, that ip we can get from request.META['REMORE_ADDR'] but where to put this and how to save to my db... Will be very glad if you could help.
models.py
class Profile(models.Model):
user = models.OneToOneField(User, unique=True)
first_name = models.CharField(max_length=200)
last_name = models.CharField(max_length=200)
date_of_birth = models.DateField()
biography = models.TextField()
contacts = models.CharField(max_length=200)
ip_address = models.GenericIPAddressField(null=True)
forms.py
class UserEditProfile(forms.ModelForm):
first_name = forms.CharField( max_length=30)
last_name = forms.CharField( max_length=30)
date_of_birth =
forms.DateField(widget=SelectDateWidget(years=BIRTH_YEAR_CHOICES))
biography = forms.Textarea()
contacts = forms.CharField()
def __init__(self, *args, **kw):
super(UserEditProfile, self).__init__(*args, **kw)
self.fields['first_name'].initial = self.instance.first_name
self.fields['last_name'].initial = self.instance.last_name
self.fields['date_of_birth'].initial =
self.instance.date_of_birth
self.fields['biography'].initial = self.instance.biography
self.fields['contacts'].initial = self.instance.contacts
self.fields.keyOrder = [
'first_name',
'last_name',
'date_of_birth',
'biography',
'contacts'
]
def save(self, *args, **kw):
super(UserEditProfile, self).save(*args, **kw)
self.instance.first_name = self.cleaned_data.get('first_name')
self.instance.last_name = self.cleaned_data.get('last_name')
self.instance.date_of_birth =
self.cleaned_data.get('date_of_birth')
self.instance.biography = self.cleaned_data.get('biography')
self.instance.contacts = self.cleaned_data.get('contacts')
self.instance.save()
class Meta:
model = Profile
fields = (
'first_name',
'last_name',
'date_of_birth',
'biography',
'contacts'
)
exclude = ['user', 'ip_address']
view.py
def edit_profile(request):
user = Profile.objects.get(id=request.user.id)
if request.method == "POST":
form = UserEditProfile(request.POST, instance=user)
if form.is_valid():
form.save(commit=False)
return redirect('profile')
else:
form = UserEditProfile(instance=user)
args = {'form': form}
return render(request, 'edit.html', args)
You cannot pass request object into form directly. That's not the way it works. If you need to associate any request attributes to your model instances, you should do it in the views.
You could collect the request.META['REMOTE_ADDR'] which gives the IP info of the logged in user in the view and associate it to yourinstance` in the view itself.
You could do this in your form.is_valid() method,
if form.is_valid():
profile = form.save(commit=False)
profile.ip_address = request.META['REMOTE_ADDR']
profile.user = request.user
profile.save()
return redirect('profile')

Django UserCreationForm add request.user.pk ?

Hi i need add request user pk to UserCreationForm. I try many times, but with out results. In my dashboard i have user owner and i have user seller.
One model for all 3 types user. So Owner can create another user with role=seller, but for this i need add parent field with param=request.user.pk to seller
Custom UserModel
from django.db import models
from django.contrib.auth.models import AbstractUser
USER = 0
OWNER = 1
SELLER = 2
user_type_choice = (
(USER, 'User'),
(OWNER, 'Owner'),
(SELLER, 'Seller'),
)
class User(AbstractUser):
role = models.CharField(max_length=100, choices=user_type_choice, default=USER)
idn = models.CharField(max_length=10, blank=True, default=None, null=True)
mobile = models.CharField(max_length=15, blank=True, default=None, null=True)
parent = models.ForeignKey('self', null=True, blank=True)
tariff = models.IntegerField(default=None, null=True, blank=True)
class Meta(AbstractUser.Meta):
swappable = 'AUTH_USER_MODEL'
forms.py
class SellerRegisterForm(UserCreationForm):
email = forms.EmailField(required=True)
first_name = forms.CharField(required=False)
last_name = forms.CharField(required=False)
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2') """try add and remove 'parent' here in felds """
def save(self, commit=True):
user = super(SellerRegisterForm, self).save(commit=False)
user.email = self.cleaned_data['email']
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.role = ROLE_SELLER
# try add user.parent = self.request.user.pk
# but it does not work
if commit:
user.save()
return user
views.py
def register_seller(request):
if request.method == 'POST':
form = SellerRegisterForm(request.POST) # create form object
if form.is_valid():
#try add new_form = form.save(commit=False)
# new_form.parent = request.user.pk
# new_form.save() but it not working
form.save()
return HttpResponseRedirect('/accounts/login')
else:
form = SellerRegisterForm()
return render(request, 'register_owner.html', {'form': form})
You need to pass the user object through the form's __init__ method.
class SellerRegisterForm(UserCreationForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(SellerRegisterForm, self).__init__(*args, **kwargs)
and in your view:
form = SellerRegisterForm(request.POST, user=request.user)
Then simply use self.user anywhere in your form class.

Create registration form for extended existing User model in Django 1.7

I created extended User model in models.py as below:
class Employee(models.Model):
user = models.OneToOneField(User)
customfield1 = models.CharField(max_length=100)
customfield2 = models.CharField(max_length=100)
and I want to add these fields to registration form. I analyzed this topic. This is the right solution but i can't apply into my site. I designed registration form but i can't register user. Codes i am using that is here:
forms.py(This is my original form but this doesn't save Employee data into db):
class AdvancedRegistrationForm(UserCreationForm):
customfield = forms.CharField(max_length=100,label="Address")
class Meta:
model = User
fields = ('first_name', 'last_name', 'username', 'email', 'customfield1', 'customfield2')
def save(self, commit=True):
user = super(AdvancedRegistrationForm, self).save(commit=False)
user.first_name = self.cleaned_data['first_name']
user.last_name = self.cleaned_data['last_name']
user.username = self.cleaned_data['username']
user.email = self.cleaned_data['email']
if commit:
user.save()
return user
views.py:
def register(request):
if request.method == 'POST':
form = AdvancedRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect("/../login")
else:
form = AdvancedRegistrationForm()
return render_to_response("register.html", {
"form": form,
}, RequestContext(request))
forms.py(This is the form that i create according to this solution but it doesn't register/save anything):
class AdvancedRegistrationForm(forms.ModelForm):
def __init__(self, instance=None, *args, **kwargs):
_fields = ('first_name', 'last_name', 'username', 'email', )
_initial = forms.model_to_dict(instance.user, _fields) if instance is not None else {}
super(AdvancedRegistrationForm, self).__init__(initial=_initial, instance=instance, *args, **kwargs)
self.fields.update(forms.fields_for_model(User, _fields))
class Meta:
model = Employee
exclude = ('user',)
def save(self, *args, **kwargs):
u = self.instance.user
u.first_name = self.cleaned_data['first_name']
u.last_name = self.cleaned_data['last_name']
u.username = self.cleaned_data['username']
u.email = self.cleaned_data['email']
u.save()
profile = super(AdvancedRegistrationForm, self).save(*args,**kwargs)
profile.user = u
profile.customfield = self.cleaned_data['customfield']
return profile

Categories