hello guys in django i tryed to make a simple custom user creation form extends as UserCreationForm .everything works but after save the record in database dont have password and i dont know why is that happening.
help me plz
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class MyRegistrationForm(UserCreationForm):
email=forms.EmailField(required=True)
first_name = forms.TextInput()
last_name = forms.TextInput()
class Meta:
model=User
fields=('username','email','first_name','last_name','password1','password2')
def save(self,commit=True):
user=super(UserCreationForm,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']
if commit:
user.save()
return user
and in the view the code is :
def register_user_view(request):
if request.method == 'POST':
form=MyRegistrationForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/success')
args={}
args.update(csrf(request))
args['form']=MyRegistrationForm().as_ul()
print(args)
return render_to_response('register.html',args)
def register_succesfull_view(request):
return render_to_response('registersucc.html')
in database
You need to put the current class, not the parent class, in the call to super:
user=super(MyRegistrationForm, self).save(commit=False)
The way you had it meant that it was skipping the parent and going straight to the grandparent, ie ModelForm, which doesn't have the custom set_password logic.
Note though that since you are using Python 3 you don't need any parameters to super at all:
user=super().save(commit=False)
which would have avoided your problem.
Related
I have made a form which name is MeasurementsForm by using Measurements model. by whenever I use form.save() in views, it throws an error and does not store data. but if i do not use form.save() it does not throw an error also does not store data. in Measurements model, I have a field name patient which has foreign key relation with user sign up custom model. now how to fix this and store data after submitting the form.
my models:
class Measurements(models.Model):
d_value=models.IntegerField()
created=models.DateTimeField(auto_now_add=True)
patient=models.ForeignKey(UserSignupModel,on_delete=models.CASCADE)
def __str__(self):
return str(self.patient)
my forms :
class MeasurementsForm(forms.ModelForm):
d_value=forms.IntegerField(help_text="insert the diabetes")
class Meta:
model=Measurements
fields=('d_value',)
my views:
def measurement(request):
if request.method=="POST":
form=MeasurementsForm(request.POST)
if form.is_valid():
form.save()
return redirect('home')
else:
form=MeasurementsForm()
return render(request,'diabetes/measurement.html',{'form':form})
The reason this fails is because your form never specifies the patient, and when you submit it to the database, the database will thus reject this.
You can set the .patient of the instance wrapped in the form. If the UserSignupModel is for example the user model (you specified with the AUTH_USER_MODEL [Django-doc]), then we can set this with:
from django.contrib.auth.decorators import login_required
#login_required
def measurement(request):
if request.method=="POST":
form=MeasurementsForm(request.POST)
if form.is_valid():
form.instance.patient = request.user
form.save()
return redirect('home')
else:
form=MeasurementsForm()
return render(request,'diabetes/measurement.html',{'form':form})
Note: You can limit views to a view to authenticated users with the
#login_required decorator [Django-doc].
I am practicing django user registration using UserCreationForm() and User() class.
My froms.py code is.
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
from django import forms
class user(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
My views.py code for this is.
def register(request):
if request.method == 'POST':
form = forms.user(request.POST)
if form.is_valid():
form.save(commit=False)
form.email = form.cleaned_data.get('email')
form.save()
#context = {'form':form, 'er':form.errors}
return redirect('register')
else:
form = forms.user()
context = {'form':form, 'er':form.errors}
return render(request, 'register/register.html', context)
I did not use authenticate() or login() in the registration system.
I have three questions. **In case of using same browser.
When I register does the user automatically log in and create a session number or does not?
If does log in and generate a session value, what happens if registers again with a new value from same browser? Does system delete previous session and generate new session or something else happens.
If I have used authenticate() and login(), what would happen if I try to register again?
It depends on your implementation. As long as you only save a user the user is only written to your DB. https://docs.djangoproject.com/en/2.2/topics/auth/default/#how-to-log-a-user-in
If you successfully created a user, you can't create a user with the same username again as the username is a unique identifier in the Django User Model.
To see if something is written to your session you can look into your DB.
Besides you might consider using an activation mail.
so i'm making a generic "accounts" page in django. I've used the django-registration plugin, and currently have a (djang-standard) User object, as well as a UserProfile and UserProfileForm object.
This is a question of style, or best-practices, i suppose. Is what i'm planning "right" or is there a "better/recommended/standard way" to do this?
What i'm planning on doing is creating the UserProfile from the request.user ie:
form = UserProfileForm(instance=User)
(and sending that form to the view), and in the UserProfileForm:
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
def __init__(self,*args,**kwargs):
super(UserProfileForm, self).__init__(*args, **kwargs)
if kwargs.has_key('instance'):
self.user = kwargs['instance']
where my UserProfile is pretty much like so:
class UserProfile(models.Model):
user = models.OneToOneField(User)
points = models.IntegerField(default=0) #how is the user going with scores?
and where User is of the django.contrib.auth.models variety.
Ok! The handling of the editing and saving will either be done via the mixin django stuff or, more likely because i haven't read up on mixins my own user-defined view that handles post and gets. But ignoring that - because i'm sure i should be using the mixins - is the above "right?" or are there suggestions?
cheers!
Take a look at user profiles on the django docs, the basics are listed there. You should also take a look at using a form in a view.
Some specific feedback:
You got the UserProfile model right, but you have to create an instance of one every time a new user is added (either through the admin interface or programmatically in one of your views). You do this by registering to the User post_save signal:
def create_user_profile(sender, instance, created, **kwargs):
if created:
UserProfile.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
You should init the ModelForm with an instance of the UserProfile, not User. You can always get the current user profile with request.user.get_profile() (if you define AUTH_PROFILE_MODULE in settings.py). Your view might look something like this:
def editprofile(request):
user_profile = request.user.get_profile()
if request.method == 'POST':
form = UserProfileForm(request.POST, instance=user_profile)
if form.is_valid():
form.save()
return HttpResponseRedirect('/accounts/profile')
else:
form = UserProfileForm(instance=user_profile)
# ...
No need for the init override in your ModelForm. You will be calling it with a UserProfile instance, anyway. If you want to create a new user, just call the User constructor:
user = User()
user.save()
form = UserProfileForm(instance = user.get_profile())
# ...
I have a Client model with a OneToOne relationship to User, to extend the User model.
I need to be able to register a user (with a form that includes both the User and Client fields), and for that I used django-registration. Here is the view for registration, based on some snippets I found:
def register_client(request):
if request.method == 'POST':
userform = UserForm(request.POST, prefix='user')
clientform = ClientForm(request.POST, prefix='client')
if userform.is_valid() and clientform.is_valid():
user = userform.save()
client = clientform.save(commit=False)
client.user = user
client.save()
login(request, user)
return HttpResponseRedirect('/webapp/')
else:
return HttpResponse('error!')
else:
userform = UserForm(prefix='user')
clientform = ClientForm(prefix='client')
t = loader.get_template('register.html')
c = RequestContext(request, {
'userform':userform,
'clientform':clientform,
})
return HttpResponse(t.render(c))
And here are my Forms:
from registration.forms import RegistrationForm
class UserForm(RegistrationForm):
def save(self):
new_user = User.objects.create_user(
username=self.cleaned_data['username'],
email = self.cleaned_data['email'],
password=self.cleaned_data['password1'])
new_user.backend='django.contrib.auth.backends.ModelBackend'
new_user.save()
return new_user
class ClientForm(forms.ModelForm):
class Meta:
model = Client
exclude = ['user']
I implemented the save() method for UserForm, since RegistrationForm doesn't implement one like any typical form.
Why does one have to go through all the trouble to implement some backend in order to just save a form?
Is there any problem with this simple way? It does work.
(I also added the new_user.backend='django.contrib.auth.backends.ModelBackend' so I could login the user automatically after registration.)
I'm not sure how to answer your question. If your code works then I don't see a problem. But as zaphod said, django-registration does the saving and activating of the user for you.. If you want to add extra data to your user then use django-profiles like zaphod suggested too.
I myself use django-userena. It is like django-registration and django-profiles in one.
Why do you need to save the User model? django-registration does it for you, unless you need some different functionality.
If you want to store some extra information per user, it might be better to use User profiles.
I'm working on an app that has three "profile" models types. Each of these models has a foreign key to the contrib.auth.models User model.
I would like to have a single sign on for each model type and provide a redirect via classmethod depending on which "profile" model type is related to the logged in user.
Here's some pseudo-code to illustrate what I would like to do:
from django.contrib.auth import authenticate, login
from django.http import HttpResponse, HttpresponseRedirect
from lib.forms import Loginform #extends the built-in AuthenticationForm
def login_user(request):
if request.method == 'POST':
form = LoginForm(data=request.POST)
if form.is_valid():
cleaned_data = form.cleaned_data
user = authenticate(username=cleaned_data.get('username'), \
password=cleaned_data.get('password'))
if user:
login(request, user)
#Determine the content type of the model related to the user
#get the correct redirect value from an #classmethod
#called: after_login_redirect for that type and...
return HttpResponseRedirect(klass.after_login_redirect())
else:
response = form.errors_as_json()
return HttpResponse(json.dumps(response, ensure_ascii=False), \
mimetype='application/json')
Is it possible to leverage the ContentTypes framework to do this? or am I better off just writing a class resolver that loops over an array of the "profile" classes? I'm not seeing a way I can do this with ContentTypes from the User class, unless someone knows a workaround.
Thanks in advance,
Brandon
[SOLVED]
So, what I ended up doing was creating a UserContentType junction model that looks like this:
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
class UserContentType(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
Then, I made a pre-save signal to fire a get or create if the instance of one of the three "profile" models I have doesn't have an id:
from django.contrib.contenttypes.models import ContentType
from lib.models import UserContentType
def set_content_type_for_user(sender, **kwargs):
instance = kwargs.get('instance')
content_type = ContentType.objects.get_for_model(instance)
user = instance.user
if not instance.id:
user_content_type, \
created = UserContentType.objects.get_or_create(user=user, \
content_type=content_type, \
defaults={'user' : user, 'content_type' : content_type})
Then, in my custom login view which is posted to via ajax, I can get the content type associated with the User instance and get the URL to redirect to from the 'after_login_redirect()' classmethod on that content type. :)
def login_user(request):
if request.method == 'POST':
form = LoginForm(data=request.POST)
if form.is_valid():
cleaned_data = form.cleaned_data
user = authenticate(username=cleaned_data.get('username', ''),
password=cleaned_data.get('password', ''))
if user:
login(request, user)
user_content_type = UserContentType.objects.get(user=user)
redirect_path =
user_content_type.content_type.\
model_class().after_login_redirect_path()
response = {'redirect_path' : redirect_path}
else:
response = form.errors_as_json()
return HttpResponse(json.dumps(response, \
ensure_ascii=False), mimetype='application/json')
This way, I don't have to monkeypatch User. I hope this helps someone out. If there's a way I can improve on this, I'd love to hear some ideas.
Thanks,
Brandon