How to overwrite django-redux default user registration form - django

When the default django-registration-redux registration page loads, it displays fields for username, email, password, along with labels instructing the user on minimum xters for username, and a list of instructions on setting password.
I want to be able to add some fields to the form, also, I want to remove the list of instruction labels. I could do it with JS but how do i overwrite the class from the django-registration-redux.
Pls i really need help. I have tried subclassing different classes, yet no headway.

You can remove help text with the below code. In your app forms.py, write below code:
from registration.forms import RegistrationForm
class MyRegForm(RegistrationForm):
def __init__(self,*args,**kwargs):
for fieldname in ['username','email', 'password1', 'password2']:
self.fields[fieldname].help_text = None
self.fields[fieldname].labels = None

Related

why can't I log in into any account until I reset its password in django admin?

I have a Profile model that has a one to one relationship with the User model from django.contrib.auth.models , when I add a new profile from the admin panel I noticed that the password field is not transformed into dots when typing , it shows the actual password , that's not the issue though , the issue is , when ever I create a new profile which in turns creates a new User , and mark the is staff attribute as true, I can't log in into the admin panel with that created account, unless I reset the password manually with
python manage.py changepassword the-user-name
after I have reset the password and only then even with the same password, I can log in into the account normally, does anybody know why is that happening ?
I made sure it's not a mistake in typing the password and I tried it several times until I made sure that this is what is actually happening
Update
when I enter the Users model from the Authentication and Authorization section opposed to entering it from the app name, I find that written besides the password section
Invalid password format or unknown hashing algorithm
how can I fix it ?
I forgot to say that I am using an UpdateView from generic views , and using the model Profile as the the model attribute set on that view
the code of my update view
class ProfileUpdate(UpdateView):
model = Profile
fields= [
'username',
'bio',
'avatar_thumbnail',
'location',
'tags',
'contact_information'
]
def get_object(self):
return Profile.objects.get(pk = self.kwargs.get('user_pk'))
def get_queryset(self):
base_qs = super(ProfileUpdate, self).get_queryset()
return base_qs.filter(username=self.request.user.username)
That would inherit from ModelAdmin instead of UserAdmin in your admin.py.
Can you instead try this:
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from app.models import Profile
class ProfileAdmin(UserAdmin):
def __init__(self, *args, **kwargs):
super(UserAdmin,self).__init__(*args, **kwargs)
UserAdmin.fieldsets += (('profile', {'fields': ('attr1', 'attr2')}),)
admin.site.unregister(User)
admin.site.register(Profile, ProfileAdmin)
Explanation
When you registered the Profile admin like so, admin.site.register(models.Profile), internally it was inheriting from ModelAdmin class which is perfect for all other classes. But for User we need hashing for saving the passwrd field, so there is a separate class UserAdmin that must be inherited from.
Once you inherited, the password issue was resolved but since the base model was UserAdmin, only user related fields were showing. We needed to append the profile fields for which we added the __init__ method and appended the profile fields to the admin section.

Forcing unique email address during registration with Django

Is there a simple way to force unique email address's during registration with website built with Django?
I've seen some "addons?" like HMAC, but it seems a bit too complicated for what I am trying to achieve.
Also, would it be possible to accept registration only from a list of domains? (such as only emails from "#google.com")
I had the same problem and solved it by extending the AbstractUser class to my own class MyUser and changing the defaults.
Then by making the this class MyUser as a default model class for all my users I could apply this property(unique E-Mail) to all my users on my web app.
Create an app myuser. There in models.py:
from django.contrib.auth.models import AbstractUser
#create your own user class.
class MyUser(AbstractUser):
def __init__(self, *args, **kwargs):
self._meta.get_field('email').blank = False
self._meta.get_field('email')._unique = True
super(MyUser, self).__init__(*args, **kwargs)
#Changed the defaults above.
#Give any additional field you want to associate your user with.
NOTE: AbstractUser already has all the basic fields you would want a User Model to have. For example: username, password, email etc. Check all of them here.
The last thing you would want to do is add the following in your setting.py
AUTH_USER_MODEL = 'myuser.MyUser'
This will make sure that the default user is associated with your web app is the extended(modified) MyUser class. This will provide you with all the basic functionalities that django provides for a User.
login
logout
in your views: you can get user instance in: request.user
etc.
I would like to suggest that you may need some additional code(in forms.py and views.py) to create a user through this type of class. I hope you will manage that. This should be enough to guide you in the right direction.
Maybe a library would have helped but since you needed an authentication for emails' domains as well, I think this should do the trick. In my humble opinion, you can't always depend on the 3rd party libraries for every other functionality.
Lastly, as you asked to authenticate a user coming only from a domain like #gmail.com or #outlook.com, a simple check in your django forms' clean method would do the trick. I hope you know how to handle django forms. If not, then you can learn about them in the official docs. They are an essential part of Django.
You can check the E-Mail with this logic:
email = self.cleaned_data['email']
email_source = email.split('#')[-1]
#email_source will now have values like: gmail.com, outlook.com etc
#you can now validate email_source now like:
permitted_sources = ['gmail.com' , 'outlook.com' , ]
if email_source in permitted_sources:
return cleaned_data
else:
raise forms.ValidationError('Error Message')
#Note: This logic should be kept in your clean method.
I hope this guides you. Thanks.

Extra fields Django-registration Forms

Good evening, I am using django-registration for a Web application; By using this, the form that has default django-registration only has 4 fields (username, email, password, repeat password). How to add more fields to this form and store them in the database correctly? Thank you.
I haven't used django-registrations but I found a link which might be helpful to you.
All you need to do is extend the class 'RegistrationForm' and add more fields.
Something like this:
forms.py
import from registration.forms import RegistrationForm
class CustomRegistrationForm(RegistrationForm):
extra_field = forms.EmailField()
extra_field_2 ...
Then, handle the form POST and save these details.
http://django-registration.readthedocs.io/en/2.0.1/forms.html

Manage UserCreationForm properties and fields

I am new in Django and even after trying thoroughly to find an answer for this question, I couldn't find any. =/
I am using UserCretionForm to create my users and I wanted to know a couple of things:
1 - How can I manage this form's properties? (e.g. I don't want to show the tips like "Required. 30 charact..." or "Enter the same password as above, for verification.")
2 - I want to make it show other customized fields. How can I do it? (please, try to be clear where I have to write the codes you'll show me as I am not an expert =D ). (e.g. Here in Brazil we have some national info I need to store. That is why I need these fields.)
Thanks in advance! (Y)
Changing the default validator messages
You can change the error messages for the default validators via the error_messages argument to a form field.
To find out which validators exist per field, check here: https://docs.djangoproject.com/en/dev/ref/forms/fields/#built-in-field-classes
class MyForm(UserCreationForm):
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['username'].error_messages = {'invalid': 'foobar'}
self.fields['password1'].error_messages = {'required': 'required, man'}
Adding new fields to an existing form
If you want to add new fields, you'd add them via subclassing (which is just python).
If you subclass UserCreationForm and add a field to it, you end up with a new form class that simply has the original's fields and your new ones.
class MyForm(UserCreationForm):
extra_field = forms.CharField()
Overriding the admin form
If you are trying to override the UserCreationForm that the admin site uses by default, you'll have to register a new ModelAdmin for the User moder.
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
from foo import MyNewUserCreationForm
class NewUserAdmin(UserAdmin):
add_form = MyNewUserCreationForm
admin.site.unregister(User)
admin.site.register(User, NewUserAdmin)

How to make email field unique in model User from contrib.auth in Django

I need to patch the standard User model of contrib.auth by ensuring the email field entry is unique:
User._meta.fields[4].unique = True
Where is best place in code to do that?
I want to avoid using the number fields[4]. It's better to user fields['email'], but fields is not dictionary, only list.
Another idea may be to open a new ticket and upload a patch with new parameter inside settings.py:
AUTH_USER_EMAIL_UNIQUE = True
Any suggestions on the most correct way to achieve email address uniqueness in the Django User model?
Caution:
The code below was written for an older version of Django (before Custom
User Models were introduced). It contains a race condition, and
should only be used with a Transaction Isolation Level of SERIALIZABLE
and request-scoped transactions.
Your code won't work, as the attributes of field instances are read-only. I fear it might be a wee bit more complicated than you're thinking.
If you'll only ever create User instances with a form, you can define a custom ModelForm that enforces this behavior:
from django import forms
from django.contrib.auth.models import User
class UserForm(forms.ModelForm):
class Meta:
model = User
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
if email and User.objects.filter(email=email).exclude(username=username).exists():
raise forms.ValidationError(u'Email addresses must be unique.')
return email
Then just use this form wherever you need to create a new user.
BTW, you can use Model._meta.get_field('field_name') to get fields by name, rather than by position. So for example:
# The following lines are equivalent
User._meta.fields[4]
User._meta.get_field('email')
UPDATE
The Django documentation recommends you use the clean method for all validation that spans multiple form fields, because it's called after all the <FIELD>.clean and <FIELD>_clean methods. This means that you can (mostly) rely on the field's value being present in cleaned_data from within clean.
Since the form fields are validated in the order they're declared, I think it's okay to occasionally place multi-field validation in a <FIELD>_clean method, so long as the field in question appears after all other fields it depends on. I do this so any validation errors are associated with the field itself, rather than with the form.
What about using unique_together in a "different" way? So far it works for me.
class User(AbstractUser):
...
class Meta(object):
unique_together = ('email',)
Simply use below code in models.py of any app
from django.contrib.auth.models import User
User._meta.get_field('email')._unique = True
In settings module:
# Fix: username length is too small,email must be unique
from django.contrib.auth.models import User, models
User._meta.local_fields[1].__dict__['max_length'] = 75
User._meta.local_fields[4].__dict__['_unique'] = True
It's amazing, but I found a best solution for me!
django-registration have form with checking uniqueness of email field: RegistrationFormUniqueEmail
example of usage here
Your form should look something like this.
def clean_email(self):
email = self.cleaned_data.get('email')
username = self.cleaned_data.get('username')
print User.objects.filter(email=email).count()
if email and User.objects.filter(email=email).count() > 0:
raise forms.ValidationError(u'This email address is already registered.')
return email
To ensure a User, no matter where, be saved with a unique email, add this to your models:
#receiver(pre_save, sender=User)
def User_pre_save(sender, **kwargs):
email = kwargs['instance'].email
username = kwargs['instance'].username
if not email: raise ValidationError("email required")
if sender.objects.filter(email=email).exclude(username=username).count(): raise ValidationError("email needs to be unique")
Note that this ensures non-blank email too. However, this doesn't do forms validation as would be appropriated, just raises an exception.
Django has a Full Example on its documentation on how to substitute and use a Custom User Model, so you can add fields and use email as username.
One possible way to do this is to have a pre-save hook on the User object and reject the save of the email already exists in the table.
I think that the correct answer would assure that uniqueness check was placed inside the database (and not on the django side). Because due to timing and race conditions you might end with duplicate emails in the database despite having for example pre_save that does proper checks.
If you really need this badly I guess you might try following approach:
Copy User model to your own app, and change field email to be unique.
Register this user model in the admin app (using admin class from django.contrib.auth.admin)
Create your own authentication backend that uses your model instead of django one.
This method won't make email field unique at the database level, but it's worth trying.
Use a custom validator:
from django.core.exceptions import ValidationError
from django.contrib.auth.models import User
def validate_email_unique(value):
exists = User.objects.filter(email=value)
if exists:
raise ValidationError("Email address %s already exists, must be unique" % value)
Then in forms.py:
from django.contrib.auth.models import User
from django.forms import ModelForm
from main.validators import validate_email_unique
class UserForm(ModelForm):
#....
email = forms.CharField(required=True, validators=[validate_email_unique])
#....
Add the below function in any of the models.py file. Then run makemigrations and migrate. Tested on Django1.7
def set_email_as_unique():
"""
Sets the email field as unique=True in auth.User Model
"""
email_field = dict([(field.name, field) for field in MyUser._meta.fields])["email"]
setattr(email_field, '_unique', True)
#this is called here so that attribute can be set at the application load time
set_email_as_unique()
Since version 1.2 (May 11th, 2015) there has been a way to dynamically import any chosen registration form using the settings option REGISTRATION_FORM.
So, one could use something like this:
REGISTRATION_FORM = 'registration.forms.RegistrationFormUniqueEmail'
This is documented here.
And here's the link to the changelog entry.
Django does not allow direct editing User object but you can add pre_save signal and achieve unique email. for create signals u can follow https://docs.djangoproject.com/en/2.0/ref/signals/. then add the following to your signals.py
#receiver(pre_save, sender=User)
def check_email(sender,instance,**kwargs):
try:
usr = User.objects.get(email=instance.email)
if usr.username == instance.username:
pass
else:
raise Exception('EmailExists')
except User.DoesNotExist:
pass
Add somewhere this:
User._meta.get_field_by_name('email')[0]._unique = True
and then execute SQL similar to this:
ALTER TABLE auth_user ADD UNIQUE (email);
The first answer here is working for me when I'm creating new users, but it fails when I try to edit a user, since I am excluding the username from the view. Is there a simple edit for this that will make the check independent of the username field?
I also tried including the username field as a hidden field (since I don't want people to edit it), but that failed too because django was checking for duplicate usernames in the system.
(sorry this is posted as an answer, but I lack the creds to post it as a comment. Not sure I understand Stackoverflow's logic on that.)
You can use your own custom user model for this purpose. You can use email as username or phone as username , can have more than one attribute.
In your settings.py you need to specify below settings
AUTH_USER_MODEL = 'myapp.MyUser'.
Here is the link that can help you .
https://docs.djangoproject.com/en/1.8/topics/auth/customizing/#auth-custom-user
from an User inherited model, redefine the attribute correctly. It should work, as is it's not usefull to have that in django core because it's simple to do.
I went to \Lib\site-packages\django\contrib\auth\models
and in class AbstractUser(AbstractBaseUser, PermissionsMixin):
I changed email to be:
email = models.EmailField(_('email address'), **unique=True**, blank=True)
With this if you try to register with email address already present in the database you will get message: User with this Email address already exists.