Django admin: created users have plain text password and can't login - django

I want to have a custom tab for staff users so in admin.py I do:
class StaffUser(User):
class Meta:
proxy = True
#admin.register(StaffUser)
class AdminUserAdmin(admin.ModelAdmin):
pass
But on the admin site, whenever I add a new user with this interface I can't log in with it since for some reason it sets it's password as plain text instead of hashing it.
I've read this post BUT if I do that and change StaffUser to inherint from AdminUserI get this other error
AttributeError: type object 'StaffUser' has no attribute '_meta'

You should declare your models in models.py (or a models package), not admin.py.
UserAdmin (there is no such thing as an AdminUser in the Django packages) is a subclass of ModelAdmin, that is, a class for registering models in the Django admin. It is not a model subclass that you can extend to make new models.
Also, if you are trying to extend the User just to distinguish users with access to the Django admin site, note that there is already an is_staff property in the default User model. And in any case, if you still want to extend the User model, you should be extending AbstractUser instead as stated in the docs.

Related

django user custom model authentication and authorization

I have created a custom user model before making any migration and I wanted to move it from the app panel to the auth panel in the admin page.
To do that I created a proxy user model:
class User(AbstractUser):
pass
class ProxyUser(User):
pass
class Meta:
app_label = 'auth'
proxy = True
and then in admin.py:
from django.contrib.auth.admin import UserAdmin
from .models import ProxyUser
admin.site.register(ProxyUser, UserAdmin)
The problem is that the auth_permission table has permissions for user and proxyuser.
Can't understand why if I'm using a proxy and only one user table was created the permissions table behaves as if there were two (proxyuser and user).
Am I missing something?
Thanks in advance
Django uses the content type framework to keep track of "permissions" for various models. Proxy models get their own permissions.
This is explained in the authentication section of Django docs:
Proxy models work exactly the same way as concrete models. Permissions are created using the own content type of the proxy model. Proxy models don’t inherit the permissions of the concrete model they subclass
I feel what you're trying to achieve with the proxy model is unnecessary. I personally wouldn't worry much about 'Users' appearing under a separate section in the Django Admin. You will instead add unnecessary complexity to the code by using a proxy model (A future developer/you would wonder wether to use the custom User class or the ProxyUser class).
You may have done all migrations and no only for your apps, if you don't specify the app to migrate, Django makes all of the migrations. On the other way, maybe you can't log into the admin site if you doesn't do it.

Django: UserCreationForm not getting Custom User Class

I'm new to Django and I'm running into an odd issue. Using Django 2.2.5 I've created a custom User class, sub-classed from AbstractBaseUser. Other than extending AbstractBaseUser the only major change I made was deleting the username field and adding my own (won't get into why here). I've added the USERNAME_FIELD = "my new username" to the model as well.
This all appeared to work well and I was able to create users. I then installed django-registration, to use that functionality and when I tried to makemigrations I ran into this error:
'django.core.exceptions.FieldError: Unknown field(s) ("My new username") specified for User`
Now, this didn't make any sense to me since the model clearly has a"My new username" field and I'd specified Django should use my User model in setting via AUTH_USER_MODEL. I knew that was working because calling get_user_model() in a shell returned my custom model.
Now here's where it gets weird, I was able to trace the issue to django-registrations, RegistrationForm. This is a form that subclasses Django's UserCreationForm. When RgistrationForm was loading or whatever during makemigrations it was producing the error because the model reference for the form was django.User not my custom user model. RegistrationForm does not declare a model and uses UserCreationForm model which happens to be User from django.contrib.auth.models.
Based on what I've read and how User is written it should reference my model, via the swappable attribute since I've set AUTH_USER_MODEL and it's supposed to swap to the model located in that settings option. For some reason, though it's not working and I don't know enough about Django to debug further.
I'm very confused by this since get_user_model() references the exact same setting and it works.
I've been able to fix this for the moment by editing the RegistrationForm model to add model = "Custom user model in django-registration's forms. I'd rather not have to distribute a custom version of this package with the rest of the site at the moment.
Any idea what's going on with swappable that might be causing this issue?
Edit 1/27/19: Update I tried sub-classing the relevant django-registration classes, but it turns out that simply importing RegistrationForm causes the issue. Importing UserCreationForm does not immediately cause a problem but if I try to check UserCreationForm.Meta.model."My new username" it provides this error:
AttributeError: type object 'User' has no attribute 'UVI_Handle'
This is consistent with the error above. At this point I'm not sure how to proceed again. I could subclass UserCreationForm, but none of django-registration will pick up on that so there doesn't seem to be a point in using it, since I'll have to copy the whole thing.
Instead of changing the package code, you should subclass:
In the case where your user model is compatible with the default
behavior of django-registration, (see below) you will be able to
subclass RegistrationForm, set it to use your custom user model as the
model, and then configure the views in django-registration to use your
form subclass. For example, you might do the following (in a forms.py
module somewhere in your codebase – do not directly edit
django-registration’s code):
from registration.forms import RegistrationForm
from mycustomuserapp.models import MyCustomUser
class MyCustomUserForm(RegistrationForm):
class Meta:
model = MyCustomUser
Above is taken from here, you should also change the urls, which is also described there.

Create editable page for user User Account

So my question is what should I look for creating a page which will allow user to add some information after the registration. I took a look at Django Profiles, but it requires lower version of Python (2.7), if I'm not mistaken.
Another thing is I need to create two types of users - I'm thinking of maybe #permission to implement it, but another point is that I want to include something like checkbox while registration, and if user chooses one type of user, he will be allowed to see default account page for this type of user which he should fill up.
I'm running Django 1.10.5 and Python 3.6.0.
Thanks in advance.
If you want to add custom fields to your user object take a look at custom user model django implementation. Then, for updating user object you can just use generic update view, it will look something like this:
from django.contrib.auth import get_user_model
class UserUpdateView(UpdateView):
model = get_user_model()
fields = ['field1', 'field2', 'field3']
template_name = "core/user_edit.html"

How make Django's auth app use my custom model "User"

Hello I am very new to Django, and I am making an app that stores a lot of information about the user. But django's auth app stores only a bit of information about the user. Is there any way I can create my own model "User" and make Django's auth app use this model. Thanks.
This has been supported since Django 1.5, and is fully covered in the documentation.
Basically, you need to subclass auth.models.AbstractUser, and set the AUTH_USER_MODEL setting to point to your new model.
You can solves your problem with UserProfile model. And you can store the user extra information in this with relation of onetone or ForeignKey with unique property field.
Django user profile
U can multi-table inheritance the user model
from django.contrib.auth import User
class MyUser(User):
//add ur required fields
Reference for in heritance.

django - Extending `auth.models.User` and usering login, logout

If I create a CustomUser model which inherits from django.contrib.auth.models.User, like so:
in models.py
class CustomUser(django.contrib.auth.models.User):
customfield = TextField()
...
Should I still be able to use
django.contrib.auth.{authenticate, login, logout} in the normal way? Do I have to make some additional configuration change? I know these methods only work on User objects, but technically my CustomUser is-a User.
Currently, authenticate(username=u, password=p) is always returning None, even with valid credentials.
Since Django 1.5 (officially but it doesn't worked for me) and "stable" in 1.6 there is a functionality to extend the User model in a clean way.
At first:
-> Take care that you load the User model only via:
from django.contrib.auth import get_user_model
User = get_user_model()
-> Once you have built the database theres no easy way to change the User model. The database relations will break and Django / South isn't able to fix it.
-> third party modules have to be compatible with that new layout and refer in it's models to "get_user_model()", too.
You have to add some Code for the admin to respect your new model:
See: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
To Override the model you need to inherit from AbstractBaseUser:
from django.contrib.auth.models import AbstractBaseUser
class MyUser(AbstractBaseUser):
...
date_of_birth = models.DateField()
height = models.FloatField()
...
REQUIRED_FIELDS = ['date_of_birth', 'height']
AbstractBaseUser provides you all attributes of the default user model. So you don't have to take care of email, username, first_name, last_name, password etc.
More info about overriding the user model: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#django.contrib.auth.models.CustomUser
In your settings link your new model:
AUTH_USER_MODEL = 'customauth.MyUser'
Please read the whole documentation of customizing the user model, there are some interesting hints for overriding the default manager, admin forms etc. Just remember that bigger changes in an existing project can be a big pain.
A short overview:
- Extend models.AbstractUser
- Set AUTH_USER_MODEL in settings.py
All details can be found here: https://docs.djangoproject.com/en/dev/topics/auth/customizing/#specifying-a-custom-user-model