My Django application uses a token based password reset mechanism, but I'm currently not able to display any error message at my template if "user is not None and str(form_token) == str(user.reset_token)" is not given
-> Error if my input is a none existing user:
File "/app/App_Accounts/views.py", line 280, in reset_password
user = form.save()
File "/app/App_Accounts/forms.py", line 315, in save
user = User.objects.get(user=form_user)
App_Accounts.models.User.DoesNotExist: User matching query does not
exist.
views.py:
def reset_password(request):
if request.method == 'POST':
form = TokenPasswordResetForm(request.POST)
if form.is_valid():
user = form.save() # line 280
....
forms.py:
class TokenPasswordResetForm(forms.Form):
error_messages = {
'password_mismatch': _('Password fields didn’t match, please try again'),
'user_or_token_mismatch': _('Unable to find user or token match'),
}
user = forms.CharField(
required=True,
strip=False,
)
reset_token = forms.CharField(
required=True,
strip=False
)
new_password1 = forms.CharField(
label=_("New Password"),
strip=False,
widget=forms.PasswordInput(attrs={'autocomplete': 'new-password'}),
)
...
def __init__(self, *args, **kwargs):
super(TokenPasswordResetForm, self).__init__(*args, **kwargs)
self.fields['user'].label = 'Username:'
...
def save(self, commit=True):
"""Save the new password."""
form_user = self.cleaned_data.get('user')
form_token = self.cleaned_data.get('reset_token')
user = User.objects.get(user=form_user) # line 315
if user is not None and str(form_token) == str(user.reset_token):
password = self.cleaned_data["new_password1"]
user.set_password(password)
user.reset_token_memorized = False
user.reset_token = reset_token_generator()
if commit:
user.save()
return user
raise forms.ValidationError(
self.error_messages['user_or_token_mismatch'],
code='user_or_token_mismatch',
)
models.py
class User(AbstractBaseUser):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
user = models.CharField(verbose_name='Username', unique=True)
...
Related
I cannot login to any account, because I receive an error:
Please enter the correct email and password for a staff account. Note that both fields may be case-sensitive.(for an admin user)
And
Please enter a correct email and password. Note that both fields may be case-sensitive.
That happens after I update a profile through the profile-detail page. It just throws me to the login page after I press the Update button on the profile-update page.
Here is all the related code:
models.py
class Customer(AbstractUser):
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['username']
objects = UserManager()
customer_id = models.AutoField(primary_key=True)
first_name = models.CharField(max_length=50, null=True, blank=True)
last_name = models.CharField(max_length=50, null=True, blank=True)
username = models.CharField(max_length=30, null=True, blank=True)
phone = models.CharField(max_length=10, default='', null=True, blank=True)
email = models.EmailField(validators=[validators.EmailValidator()], unique=True)
description = models.TextField(max_length=1000,blank=True, null=True)
gender = models.CharField('Gender', max_length=10, choices=Gender.choices,
default='Male', null=True)
featured_img = models.ImageField(verbose_name='A profile image',
upload_to='profiles',
default='products/profile_default.jpg')
password = models.CharField(max_length=100, null=True, blank=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return f'{self.email} {self.username} {self.customer_id}'
#staticmethod
def get_customer_by_email(email):
try:
return Customer.objects.get(email=email)
except:
return False
def exists(self):
if Customer.objects.filter(email=self.email):
return True
return False
class Meta:
verbose_name = 'Customer'
verbose_name_plural = 'Customers'
# unique_together = ['email']
class Profile(models.Model):
# USERNAME_FIELD = 'email'
profile_id = models.AutoField(primary_key=True)
date_created = models.DateTimeField(auto_now_add=True, null=True)
updated = models.DateTimeField(auto_now=True, null=True)
user = models.ForeignKey(Customer, on_delete=models.CASCADE,
related_name="customer", null=True)
class Meta:
verbose_name = 'Profile'
verbose_name_plural = 'Profiles'
# unique_together = ['email']
def __str__(self):
return f' {self.profiled}'
managers.py
class UserManager(BaseUserManager):
def create_user(self, email, first_name=None, description=None, gender=None, featured_img=None, username=None, last_name=None, phone=None, password=None):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
user = self.model(
email=self.normalize_email(email),
)
user.first_name = first_name
user.username = username
user.last_name = last_name
user.password = make_password(password) # change password to hash
user.phone = phone
user.featured_img = featured_img
user.description = description
# user.profile = profile
user.gender = gender
user.admin = False
user.staff = True
user.active = True
user.save(using=self._db)
return user
def create_superuser(self, email, username, password):
if not email:
raise ValueError("User must have an email")
if not password:
raise ValueError("User must have a password")
user = self.model(
email=self.normalize_email(email)
)
user.username = username
user.password = make_password(password) # chang password to hash
user.admin = True
user.staff = True
user.active = True
user.save(using=self._db)
return user
views.py
#csrf_exempt
def signup(request):
if request.method == 'POST':
form = SignUpForm(request.POST or None)
email = request.POST['email']
if Customer.get_customer_by_email(email=email) == False:
if form.is_valid():
user = form.save(commit=False)
# account = authenticate(request,
# username=email,
# password=request.POST['password'])
user.username = user.username.lower()
user.save()
login(request, user,
backend='allauth.account.auth_backends.AuthenticationBackend')
messages.success(request, 'The account was successfully created!!!')
return redirect(reverse_lazy('products:products'))
messages.error(request, f'{form.errors}')
return redirect(reverse_lazy('user-auth:register'))
return redirect(reverse_lazy('user-auth:login'))
form = SignUpForm()
context = {'form': form, 'user': request.user}
return render(request, 'auth/register/register.html', context)
class ProfileDetailView(
DetailView):
context_object_name = 'customer'
template_name = 'auth/profile_detail.html'
def get_object(self):
profile = Profile.objects.filter(user__customer_id=self.kwargs['pk']).first()
return profile.user
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['user'] = self.request.user
return context
class UpdateProfileView(LoginRequiredMixin,
UpdateView):
template_name = 'auth/profile_update.html'
form_class = ProfileUpdateForm
context_object_name = 'customer'
def get_success_url(self):
success_url = reverse_lazy('user-auth:profile-detail',
kwargs={'pk': self.request.user.customer_id})
return success_url
#method_decorator(ensure_csrf_cookie, name='dispatch')
def post(self, request, *args, **kwargs):
profile = self.get_object()
form = ProfileUpdateForm(instance=profile)
# if request.method == 'POST':
form = ProfileUpdateForm(request.POST, request.FILES, instance=profile)
if form.is_valid():
if profile:
form.save()
messages.success(request, 'Successfully updated!')
return redirect(self.get_success_url())
messages.error(request, 'Profile does not exist!')
return redirect(reverse_lazy('user-auth:signup'))
messages.error(request, 'Invalid data!')
return render(request, self.template_name, self.get_context_data())
def get_object(self):
profile = Profile.objects.filter(user__customer_id=self.kwargs['pk']).first()
return profile.user
# def get(self, request, *args, **kwargs):
# context = {}
# context["form"] = ProfileUpdateForm(instance=self.get_object())
# context['user'] = request.user
# return render(request, self.template_name, context)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context["form"] = ProfileUpdateForm(instance=self.get_object())
context['user'] = self.request.user
return context
class DeleteProfileView(LoginRequiredMixin,
DeleteView):
context_object_name = 'customer'
template_name = 'auth/profile_confirm_delete.html'
def get_success_url(self):
success_url = reverse_lazy('user-auth:profile-detail',
kwargs={'pk': self.request.user.customer_id})
return success_url
def post(self, request, *args, **kwargs):
self.request = request
if self.get_object:
messages.success(request, 'Profile deleted successfully!')
return super().delete(request, *args, **kwargs)
messages.success(request, 'Profile does not exist!')
return redirect(reverse_lazy('user-auth:signup'))
def get_object(self):
profile = Profile.objects.filter(user__customer_id=self.kwargs['pk']).first()
return profile.user
signals.py
#receiver(post_save, sender=Customer)
def create_profile(sender, instance, created, **kwargs):
user = instance
if created:
print(user)
Profile.objects.create(
user=user
)
#receiver(pre_save, sender=Customer)
def update_profile(sender, instance, **kwargs):
# print(instance)
profile = instance
if profile.customer_id is not None:
Profile.objects.update(user=profile)
#receiver(post_delete, sender=Customer)
def delete_profile(sender, instance, **kwargs):
user = instance
customer = Customer.objects.filter(email=user.email).first()
if user and customer:
# profile.delete()
customer.delete()
print('Not exists...')
forms.py
class SignUpForm(UserCreationForm):
class Meta:
model = Customer
fields = ('username','phone', 'first_name', 'last_name', 'email', 'featured_img')
# def __init__(self, *args, **kwargs):
# super(SignUpForm, self).__init__(*args, **kwargs)
# for name, field in self.fields.items():
# field.widget.attrs.update({'class': 'input'})
class ProfileUpdateForm(forms.ModelForm):
password1 = forms.CharField(
label="Password",
strip=False,
widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}),
help_text=password_validation.password_validators_help_text_html(),
required=False
)
password2 = forms.CharField(
label="Password confirmation",
widget=forms.PasswordInput(attrs={"autocomplete": "new-password"}),
strip=False,
help_text="Enter the same password as before, for verification.",
required=False
)
class Meta:
model = Customer
fields = ('username', 'phone', 'first_name', 'last_name', 'email', 'featured_img', 'description', 'gender')
def save(self, commit=True):
customer = super().save(commit=False)
email = self.cleaned_data.get('email')
customer.email = email.lower()
# customer.password = customer.set_password(self.cleaned_data['password1'])
if commit:
if customer.exists():
super(ProfileUpdateForm, self).save()
return customer
urls.py
from django.contrib.auth import views as auth_views
app_name = 'user-auth'
urlpatterns = [
path('register/', views.signup, name='register'),
path('accounts/login/', auth_views.LoginView.as_view(
template_name='auth/login/login.html',
success_url='products/'),
name='login'
),
path('accounts/logout/', auth_views.LogoutView.as_view(), name='logout'),
path('profile-detail/<int:pk>/', views.ProfileDetailView.as_view(), name='profile-detail'),
path('profile-update/<int:pk>/', views.UpdateProfileView.as_view(),
name='profile-update'),
path('profile-delete/<int:pk>/', views.DeleteProfileView.as_view(),
name='profile-delete'),
]
I have tried to delete my database and fill it in once again. Then I tried to find out why the email or password dis incorrect. Maybe they are wrong in the database. But I have no idea what's going on.
I have a register user form which is doing all the validation as expected. However, it is not saving. I am not able to figure out the reason. How do I debug it ? Any help ? I am a newbie to forms and formviews any good document with example would really help me.
class RegisterForm(forms.ModelForm):
phone_number = forms.IntegerField(required=True)
password1 = forms.CharField(widget=forms.PasswordInput())
password2 = forms.CharField(widget=forms.PasswordInput())
country_code = forms.IntegerField()
#schools = school.objects.all()
#school_name = forms.ModelChoiceField(queryset=school.objects.distinct())
MIN_LENGTH = 4
class Meta:
model = User
fields = ['username','country_code','phone_number', 'password1', 'password2',
'full_name' ]
def clean_phone_number(self):
phone_number = self.data.get('phone_number')
print(phone_number)
if User.objects.filter(phone_number=phone_number).exists():
raise forms.ValidationError(
_("Another user with this phone number already exists"))
if len(phone_number) == 10 and phone_number.isdigit():
pass
else:
raise forms.ValidationError(
_("Invalid Phone Number"))
return phone_number
def save(self, *args, **kwargs):
print("saving")
user = super(RegisterForm, self).save(*args, **kwargs)
user.set_password(self.cleaned_data['password1'])
print('Saving user with country_code', user.country_code)
user.save()
return user
Views.py
class RegisterView(SuccessMessageMixin, FormView):
template_name = 'register-2.html'
form_class = RegisterForm
success_message = "One-Time password sent to your registered mobile number.\
The verification code is valid for 10 minutes."
def form_valid(self, form):
full_name=self.request.POST["full_name"]
user = form.save()
print(user.id)
username = self.request.POST['username']
password = self.request.POST['password1']
user = authenticate(username=username, password=password)
kwargs = {'user': user}
self.request.method = 'POST'
print("User created")
The print in clean_phone_number works however, save does not work
I had issue in the my form. One of the field was disabled and the value was not captured because of that.
However to identify that I used
def form_invalid(self,form):
# Add action to invalid form phase
messages.error(self.request, form.errors)
return self.render_to_response(self.get_context_data(form=form))
I have a form and a CBV CreateView. I need to assign the request.user to the user field (Foreign Key to CustomUser model), which in the form is a hidden field (user). However, I have tried in the form init method by "self.fields['user'] = self.request.user.id" and I get the error: 'NoneType' object has no attribute 'user'. What is the most clean way of achieving this?
I have tried many different ways of doing it with no luck. ):
This is my form:
class PhoneForm(forms.ModelForm):
class Meta:
model = Phone
fields = 'user', 'phone_name', 'country', 'phone_number', 'phone_type', 'primary'
widgets = {'user': forms.HiddenInput()}
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
super(PhoneForm, self).__init__(*args, **kwargs)
self.fields['user'].widget.attrs['readonly'] = True
self.fields['user'] = self.request.user.id
self.fields['primary'].help_text = _('<strong>Check:</strong> If this is your main contact phone number.')
def clean(self):
cleaned_data = super(PhoneForm, self).clean()
user = cleaned_data.get('user')
phone_name = cleaned_data.get('phone_name')
country = cleaned_data.get('country')
phone_number = cleaned_data.get('phone_number')
phone_type = cleaned_data.get('phone_type')
primary = cleaned_data.get('primary')
print('user: ',user)
print('phone_name: ',phone_name)
print('country: ',country)
print('phone_number: ',phone_number)
print('phoe_type: ',phone_type)
print('primary: ',primary)
if "action_add" in self.request.POST:
try:
phonenum = Phone.objects.filter(user=user, country=country, phone_number=phone_number).first()
if phonenum:
raise forms.ValidationError(_('This Phone is registered already.'))
except Phone.DoesNotExist:
pass
try:
phone = Phone.objects.filter(user=user, primary=True).first()
if phone and primary:
raise forms.ValidationError(_('There is another "Primary" Phone #already.'), code='invalid')
except Phone.DoesNotExist:
pass
if "action_update" in self.request.POST:
if "country" in self.changed_data or "phone_number" in self.changed_data:
raise forms.ValidationError(_('You can´t update the Country nor the Phone number of the existing Phone.'))
try:
phone = Phone.objects.filter(user=user, primary=True).first()
if phone and primary and self.request.session['Phone_object_id'] != phone.id:
raise forms.ValidationError(_('There is another "Primary" Phone #already.'), code='invalid')
except Phone.DoesNotExist:
pass
if not phone_name and not phone_type and not phone_number:
raise forms.ValidationError(_('You have to fill out the form!'))
This is my view:
class PhoneCreateView(LoginRequiredMixin, CreateView):
form_class = PhoneForm
model = Phone
template_name = 'phones/addPhone.html'
login_url = reverse_lazy('account_login')
success_url = reverse_lazy('phonesList')
class Meta:
readonly = ('user', )
def get_form_kwargs(self):
kw = super(PhoneCreateView, self).get_form_kwargs()
kw['request'] = self.request
return kw
def get_initial(self):
phone = Phone.create(self.request.user.id)
form = self.form_class(instance=phone)
form.instance.user = CustomUser.objects.get(id=self.request.user.id)
return {'form': form, }
def get_context_data(self, **kwargs):
context = super(PhoneCreateView, self).get_context_data(**kwargs)
form = self.form_class(instance=self.object)
form.instance.user = CustomUser.objects.get(id=self.request.user.id)
context = {
'form': form,
'user': self.request.user.id,
}
return context
def form_valid(self, form):
form.instance.user = CustomUser.objects.get(id=self.request.user.id)
form.instance.status = 'A'
form.instance.status_dt = timezone.now()
form.instance.at_user = self.request.user.email
form.instance.at_ip = visitor_ip_address(self.request)
form.instance.at_dttm = timezone.now()
form.instance.at_action = 'Create Phone number'
messages.success(self.request, _('Your Phone Number has been registered.'))
return super(PhoneCreateView, self).form_valid(form)
This is my model:
class Phone(models.Model):
PHONETYPES = (
('1', _('Mobile')),
('2', _('Home')),
('3', _('Work')),
('4', _('Other')),
)
status = models.CharField(_("Record Status"), max_length=1, default='A')
status_dt = models.DateTimeField(_("Status Date"), default=timezone.now)
user = models.ForeignKey(CustomUser, verbose_name=_("User"), on_delete=models.CASCADE)
phone_name = models.CharField(_("Phone name"), max_length=20, default="PH"+str(random.randint(1,99999)))
country = models.IntegerField(_("Country Dialing Code"))
phone_number = models.CharField(_("Phone Number"), max_length=11)
phone_type = models.CharField(_("Phone Type"), max_length=1, default="4", choices=PHONETYPES)
verified = models.BooleanField(verbose_name=_('verified'), default=False)
primary = models.BooleanField(verbose_name=_('primary'), default=False)
at_user = models.CharField(_("Audit Trail (user)"), max_length=255, blank=True)
at_ip = models.GenericIPAddressField(_("Audit Trail (IP)"), protocol='both', blank=True, null=True)
at_dttm = models.DateTimeField(_("Audit Trail (Date-Time)"), default=timezone.now)
at_action = models.CharField(_("Audit Trail (Function performed)"), max_length=255, blank=True)
UniqueConstraint(fields=['user', 'country', 'phone_number'], name='user_unique_phone_number')
class Meta:
verbose_name = _("Phone Number")
verbose_name_plural = _("Phone Numbers")
#classmethod
def create(cls, user):
phone = cls(user= get_object_or_404(CustomUser, pk=user))
# phone create
return phone
def __str__(self):
return self.phone_name
I had to change a few things. First the hidden field user (which is foreign key to the user table) was taken out from the form and from the fields. Instead I used a session parameter where I stored the user id. Then I had to reformulate my method get_context_data in the view. The following is the updated code:
My new form:
class PhoneForm(forms.ModelForm):
class Meta:
model = Phone
fields = 'phone_name', 'country', 'phone_number', 'phone_type', 'primary'
#widgets = {'user': forms.HiddenInput()}
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request', None)
if self.request is None:
self.request = kwargs['instance']
super(PhoneForm, self).__init__(*args, **kwargs)
#self.fields['user'].widget.attrs['readonly'] = True
self.fields['primary'].help_text = _('<strong>Check:</strong> If this is your main contact phone number.')
def clean(self):
cleaned_data = super(PhoneForm, self).clean()
customUser = self.request.session['user_id']
phone_name = cleaned_data.get('phone_name')
country = cleaned_data.get('country')
phone_number = cleaned_data.get('phone_number')
phone_type = cleaned_data.get('phone_type')
primary = cleaned_data.get('primary')
try:
del self.request.session['validation_error']
except KeyError:
pass
if "action_add" in self.request.POST:
try:
phonenum = Phone.objects.filter(customUser=customUser, country=country, phone_number=phone_number).first()
if phonenum:
#messages.error(self.request, _('This Phone is registered already.'))
raise forms.ValidationError(_('This Phone is registered already.'))
except Phone.DoesNotExist:
pass
try:
phone = Phone.objects.filter(customUser=customUser, primary=True).first()
if phone and primary:
#messages.error(self.request, _('There is another "Primary" Phone already.'))
raise forms.ValidationError(_('There is another "Primary" Phone #already.'), code='invalid')
except Phone.DoesNotExist:
pass
if "action_update" in self.request.POST:
if "country" in self.changed_data or "phone_number" in self.changed_data:
raise forms.ValidationError(_('You can´t update the Country nor the Phone number of the existing Phone.'))
try:
phone = Phone.objects.filter(customUser=customUser, primary=True).first()
if phone and primary and self.request.session['Phone_object_id'] != phone.id:
raise forms.ValidationError(_('There is another "Primary" Phone #already.'), code='invalid')
except Phone.DoesNotExist:
pass
if not phone_name and not phone_type and not phone_number:
raise forms.ValidationError(_('You have to fill out the form!'))
return cleaned_data
and my new get_context_data method in the view is:
def get_context_data(self, **kwargs):
#Use this to add extra context.#
context = super(PhoneCreateView, self).get_context_data(**kwargs)
form = self.form_class(instance=self.object)
form.instance.customUser = CustomUser.objects.get(id=self.request.user.id)
self.request.session['user_id'] = self.request.user.id
return context
I have a project in django and I am creating a simple form that will allow a user to create a simple profile that asks for name and date of birth and location. I am getting a key error with the date of birth section and I dont know exactly why.
I am trying to collect data and store it to then later added it to a database record.
Here is the views file:
cd = form.cleaned_data
first_name = cd['first_name']
last_name = cd['last_name']
dob_month = cd['dob_month']
dob_day = ['dob_day']
dob_year = ['dob_year']
city = cd['city']
state = cd['state']
phone = cd['phone']
privacy = cd['privacy']
Here is the models file:
user = models.ForeignKey(User, on_delete=models.CASCADE) # server
first_name = models.CharField(max_length=25, default='first')
last_name = models.CharField(max_length=25, default='last')
dob_month = models.IntegerField(default=0)
dob_day = models.IntegerField(default=0)
dob_year = models.IntegerField(default=0)
city = models.CharField(max_length=45) # user
state = models.CharField(max_length=25, default='state')
phone = models.BigIntegerField(default=0) # user
privacy = models.SmallIntegerField(default=1) # user
created = models.DateTimeField(auto_now_add=True) # server
here is the forms file:
class ProfileForm(forms.ModelForm):
split_choices = (('1', 'public'),
('2', 'private'))
privacy = forms.TypedChoiceField(
choices=split_choices, widget=forms.RadioSelect, coerce=int
)
dob = forms.DateField(widget=extras.SelectDateWidget)
class Meta:
model = Profile
fields = ['first_name', 'last_name', 'dob', 'city', 'state', 'phone', 'privacy']
and finally, here is the error that I am getting:
KeyError at /setup_profile/
'dob_month'
Request Method: POST
Request URL: http://127.0.0.1:8000/setup_profile/
Django Version: 1.8.6
Exception Type: KeyError
Exception Value:
'dob_month'
Exception Location: C:\Users\OmarJandali\Desktop\opentab\opentab\tab\views.py in profile_setup, line 292
first_name 'omar'
last_name 'jandali'
dob_month '1'
dob_day '23'
dob_year '2024'
city 'riverside'
state 'ca'
phone '9515343666'
privacy '1'
submit 'submit'
UPDATED:
here is the views.py file but the issue is with the cd['dobv_month'], but i have no idea why the error is coming from there.
def profile_setup(request):
if 'username' not in request.session:
return redirect('login')
else:
# the following is just going to grab the currently logged in user and
# save the profile information to the appropriate user
username = request.session['username']
currentUser = User.objects.get(username = username)
# the following is the provessing for the form where the user entered
# the profile informaiton
if request.method == 'POST':
form = ProfileForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
first_name = cd['first_name']
last_name = cd['last_name']
dob_month = cd['dob_month']
dob_day = ['dob_day']
dob_year = ['dob_year']
city = cd['city']
state = cd['state']
phone = cd['phone']
privacy = cd['privacy']
# this is the new record that is going to be created and saved
new_profile = Profile.objects.create(
user = currentUser,
first_name = first_name,
last_name = last_name,
dob_month = dob_month,
dob_day = dob_day,
dob_year = dob_year,
city = city,
state = state,
phone = phone,
privacy = privacy,
)
return redirect('home_page')
else:
# this is what is going to be saved into the html file and used to
# render the file
form = ProfileForm()
message = 'fill out form below'
parameters = {
'form':form,
'currentUser':currentUser,
'message':message,
}
return render(request, 'tabs/profile_setup.html', parameters)
Let's say your model name is User.
forms.py:
from .models import User
class UserForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(UserForm, self).__init__(*args, **kwargs)
class Meta:
model = User
fields = '__all__'
and views.py:
def user_create(request):
form = UserForm(request.POST or None)
if request.method == 'POST':
form = UserForm(request.POST or None)
if not form.is_valid():
print form.errors
return render(request, 'user_create.html', {'form': form})
else:
first_name = form.cleaned_data.get("first_name")
last_name = form.cleaned_data.get("last_name")
# pass your extra fields here
new_user = User.objects.create_user(
user=user,
first_name=first_name,
last_name=last_name,
)
new_user.save()
return redirect('where you want to redirect',)
return TemplateResponse(request, 'user_create.html')
finally user will be save.
Read docs:https://docs.djangoproject.com/en/1.11/topics/forms/modelforms/
class CustomAccount(models.Model):
user = models.OneToOneField("auth.User")
role = models.CharField(max_length = 50, default = 'student', choices=APPROVAL_CHOICES)
balance = models.FloatField( default = 0 )
timezone = models.CharField(max_length = 200)
def __str__(self):
return self.user.username +" ["+ self.role + "]"
class CustomAccountForm(forms.ModelForm):
username = forms.CharField(max_length=30 )
email = forms.EmailField(max_length=255 )
password1 = forms.CharField(label= "Password",widget=forms.PasswordInput())
password2 = forms.CharField(label="Password confirmation", widget=forms.PasswordInput , help_text="Enter the same password as above, for verification.")
def save(self, commit= True):
user = User.objects.create_user(username = self.cleaned_data['username'], email = self.cleaned_data['email'] , password = self.cleaned_data['password1'])
user.save()
self.user = user
return super(CustomAccountForm, self).save(commit=commit)
def clean_username(self):
username = self.cleaned_data["username"]
try:
User.objects.get(username=username)
except User.DoesNotExist:
return username
raise forms.ValidationError("A user with that username already exists.")
def clean_password2(self):
password1 = self.cleaned_data.get("password1", "")
password2 = self.cleaned_data["password2"]
if password1 != password2:
raise forms.ValidationError("The two password fields didn't match.")
return password2
def clean_email(self):
email = self.cleaned_data["email"]
try:
User.objects.get(email=email)
except User.DoesNotExist:
return email
raise forms.ValidationError("A user with that emailaddress already exists.")
class Meta:
model = CustomAccount
exclude = ['balance','user']
I want to create Custom account in Django Admin section using single form which has fields of auth.User and CustomAccount Model. I have getting error IntegrityError at /admin/mylogin/customaccount/add/
NOT NULL constraint failed: mylogin_customaccount.user_id
Since you are getting a not null error, I think you need to specify that the field is not required. Here is an example from one of my apps. This says that the form field is not required.
class arunModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
myuser = kwargs.pop('user', None)
super(arunModelForm, self).__init__(*args, **kwargs)
self.fields['nanoadded'].required = False
self.fields['response'].required = False
I also include this in my models so that my model fields can be null, like this:
class arun(models.Model):
auser = models.CharField(max_length=50, null=True)
adate = models.DateField(null=True)
atime = models.TimeField(null=True)
If I still get not null errors after I do both of these things, I fill the field with a place holder value to allow me to further investigate the problem.
You have removed the user from the form and in the save method, you have assigned self.user in save method. So when saving the form, the user attribute is not used for CustomAccountForm and the user field for CustomAccount is None.
Your save method should look like:
def save(self, commit= True):
user = User.objects.create_user(username =self.cleaned_data['username'], email = self.cleaned_data['email'] , password = self.cleaned_data['password1'])
user.save()
obj = super(CustomAccountForm, self).save(commit=False)
obj.user = user
obj.save()