How do I retrieve the name of superuser in Django? - django

users = User.objects.all()
post.author = users.name
Considering that User is where superuser's info is stored in the database. It throws an error as:
'Query Set' object has no attribute 'name'

from django.contrib.auth.models import User
superusers = User.objects.filter(is_superuser=True)
superuser_names = [user.username for user in superusers]

If you are on a view that superuser is logged in you can check username by:
if request.user.is_superuser:
name = request.user.username
else:
name = None

user = User.objects.all() returns a queryset containing all the user in the db, therefore you can't use .name on it.
As far as I understood your problem you want the username of user therefore you should use user.username if want first name use user.first_name, this will work only on single object NOT on the queryset. You can user user.is_superuser to find if user is superuser or not.
This will help -> Read More in Docs

Related

password dont change in views.py on django

I'm trying to change a user's password on my views.py and whenever I change the password, I lose my connection and access to my account
my view.py:
user = User.objects.get(id=request.user.id)
user.password = make_password(request.POST.get("password"))
user.save()
A User object normally has a .set_password(…) method [Django-doc], so you can update that password with:
request.user.set_password(request.POST['password'])
request.user.save()
You can omit fetching the user object, since request.user aleady does that. Using user = User.objects.get(id=request.user.id) is thus an extra query that only is equivalent to request.user.
try using set_password instead of make_password like that
user = User.objects.get(id=request.user.id)
user.password = set_password(request.POST.get("password"))
user.save()
The following is an explanation provided by the Django documentation https://docs.djangoproject.com/en/3.2/topics/auth/default/#changing-passwords

Allowing user to Submit form once in Django

i want that user can submit a particular form only once. Is it possible without any js,react.. actually by using django only ??
i have tried something like that --
def apply(request):
p=0
if request.method=="POST":
p=1
...do something..
else:
...do something...
i have tried to catch the value of p=1, and try to not return the html is it's submitted once , but each time reload makes the value of p=0.
i have to save the session ?? or what will be the right way to do this ?
can anyone suggest anything please?
I suggest adding a field name form_submitted as BooleanField to your User model(by abstracting the based User model) to check and see if that user submitted the form. You can get the current logged in user from request.user.
models.py:
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
# also do this if you have custom user model
form_submitted = models.BooleanField(default=False)
class Meta:
db_table = "users"
views.py:
def apply(request):
if request.method=="POST":
user = request.user
if not user.form_submitted:
# save the form
user.form_submitted = True
user.save()
else:
# this user already submitted the form

How to create users in Django 1.5

I have extended my UserManager with a new method create_inactive_user. But how do I use UserCreationForm?
class UserManager(UserManager):
def create_inactive_user(self, username, email, password):
user = self.create_user(username, email, password)
user.is_active = False
salt = hashlib.sha1(str(random.random())).hexdigest()[:5]
activation_key = hashlib.sha1(salt+user.username).hexdigest()
user.activation_key = activation_key
user.save()
return user
I can see in https://github.com/django/django/blob/master/django/contrib/auth/forms.py that UserCreationForm is a ModelForm which saves the object, so how can I be sure to sign up the users though create_inactive_user() in my FormView?
Is it something like this:
class SignupView(FormView):
form_class = UserCreationForm
template_name = 'signup.html'
def form_valid(self, form):
User.objects.create_inative_user(form.cleaned_data['username'], form.cleaned_data['email'], form.cleaned_data['password'])
return super(SignupView, self).form_valid(form)
Looks like django-registration does exactly what you're trying to do, with all views and forms included. Looks like their approach is to use a generic form, not a model one. From the quickstart doc:
A user signs up for an account by supplying a username, email address and password.
From this information, a new User object is created, with its is_active field set to False. Additionally, an activation key is
generated and stored, and an email is sent to the user containing a
link to click to activate the account.
Upon clicking the activation link, the new account is made active (the is_active field is set to True); after this, the user can log in.

I'm extending User model in django and I'm not able to authenticate because of raw password

So the problem is I have extended User model in django. and I have written views for it.
Here is my models code :-
class StudentProfile(User):
batch = models.CharField(max_length=10)
course = models.CharField(max_length=20)
date_of_birth = models.DateField()
answer = models.CharField(max_length=20)
contact = models.CharField(max_length=20)
here is my auth backend file :-
from quizapp.models import StudentProfile
class StudentAuthenticationBackend(object):
def authenticate(self, username=None, password=None):
try:
student = StudentProfile.objects.get(username=username)
if student.check_password(password):
return student
except StudentProfile.DoesNotExist:
pass
return None
def get_user(self, user_id):
try:
return StudentProfile.objects.get(pk=user_id)
except StudentProfile.DoesNotExist:
return None
And I have made changes in seetings.py
AUTHENTICATION_BACKENDS = (
'quizapp.backends.StudentAuthenticationBackend',
'django.contrib.auth.backends.ModelBackend',
)
I'm printing username,password and authentication user. This is what i got :-
When using django created superuser
>> a = authenticate(username="super",password="super")
>> print(a)
>> super
But when using user created by form,
>> b = authenticate(username="test",password="123")
>> print(b)
>> None
I have cross checked username and password and it's true.
So but in auth_user table, username is super and password is encrypted but for test user, username is user and password is 123.
So the problem must be django is taking 123 is encrypted password and using decrypted version of it to authenticate.
Is there any way to solve this?
I have used OneToOneField and added extra fields in StudentProfile model. Now I'm using forms and registering user with it.
This is the view code :-
def register_page(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
user = StudentProfile.objects.create(
username=form.cleaned_data['username'],
password=form.cleaned_data['password1'],
batch=form.cleaned_data['batch'],
first_name=form.cleaned_data['first_name'],
last_name=form.cleaned_data['last_name'],
course=form.cleaned_data['course'],
date_of_birth=form.cleaned_data['date_of_birth'],
secret_question=form.cleaned_data['secret_question'],
answer=form.cleaned_data['answer'],
contact=form.cleaned_data['contact']
)
return HttpResponseRedirect('/register/success/')
else:
form = RegistrationForm()
variables = RequestContext(request, {'form': form})
return render_to_response('registration/register.html',variables)
And I'm getting IntegrityError at /register/
null value in column "user_id" violates not-null constraint error.
Is there any way to fix this?
From the Django authenication docs section on storing additional information about users:
If you'd like to store additional information related to your users, Django provides a method to specify a site-specific related model -- termed a "user profile" -- for this purpose.
To make use of this feature, define a model with fields for the additional information you'd like to store, or additional methods you'd like to have available, and also add a OneToOneField named user from your model to the User model. This will ensure only one instance of your model can be created for each User.
So you shouldn't subclass User at all -- that's the root of your problem. Instead, you should create another model with a one-to-one relationship with User and add your fields there.

Using email as username with django

I have run into the following error trying to create a user in django:
>>> email = 'verylongemail#verylongemail.com'
>>> user_object = User.objects.create_user(username=email, email=email, password='password')
Data truncated for column 'username' at row 1
It seems Django has a limit on the number of chars allowed in a username. How would I get around this?
I've had to modify the auth_user table by hand to make the field longer and then convert emails into a username by removing the # symbol and the period (maybe other characters too, it's really not a great solution). Then, you have to write a custom auth backend that authenticates a user based on their email, not the username, since you just need to store the username to appease django.
In other words, don't use the username field for auth anymore, use the email field and just store the username as a version of the email to make Django happy.
Their official response on this topic is that many sites prefer usernames for auth. It really depends if you are making a social site or just a private site for users.
If you override the form for Django users you can actually pull this off pretty gracefully.
class CustomUserCreationForm(UserCreationForm):
"""
The form that handles our custom user creation
Currently this is only used by the admin, but it
would make sense to allow users to register on their own later
"""
email = forms.EmailField(required=True)
first_name = forms.CharField(required=True)
last_name = forms.CharField(required=True)
class Meta:
model = User
fields = ('first_name','last_name','email')
and then in your backends.py you could put
class EmailAsUsernameBackend(ModelBackend):
"""
Try to log the user in treating given username as email.
We do not want superusers here as well
"""
def authenticate(self, username, password):
try:
user = User.objects.get(email=username)
if user.check_password(password):
if user.is_superuser():
pass
else: return user
except User.DoesNotExist: return None
then in your admin.py you could override with
class UserCreationForm(CustomUserCreationForm):
"""
This overrides django's requirements on creating a user
We only need email, first_name, last_name
We're going to email the password
"""
def __init__(self, *args, **kwargs):
super(UserCreationForm, self).__init__(*args, **kwargs)
# let's require these fields
self.fields['email'].required = True
self.fields['first_name'].required = True
self.fields['last_name'].required = True
# let's not require these since we're going to send a reset email to start their account
self.fields['username'].required = False
self.fields['password1'].required = False
self.fields['password2'].required = False
Mine has a few other modifications, but this should get you on the right track.
You have to modify the username length field so that syncdb will create the proper length varchar and you also have to modify the AuthenticationForm to allow greater values as well or else your users won't be able to log in.
from django.contrib.auth.forms import AuthenticationForm
AuthenticationForm.base_fields['username'].max_length = 150
AuthenticationForm.base_fields['username'].widget.attrs['maxlength'] = 150
AuthenticationForm.base_fields['username'].validators[0].limit_value = 150