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.
Related
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.
Hello everyone let me ask something about the admin interface and how can I handle my users by app.
Well so sorry I'm nooby first of all. So, I need to create a new app for basically take some quiz so I will need users and these users within my app should have a different role as a student or teacher and so on.
The thing is that I don't know if the admin Django interface is just for the DB models or whether I can use it as a security layer in my app.
Or otherwise, I should create a buck of tables in my app model for users and roles and then handle everything from the model because the admin is just the DB access. what could you tell me? thanks so much.
From Django's documentation about Django admin - Link
model-centric interface where trusted users can manage content on your site.
Django comes with a user model, you can extend it to represent teachers and students as described in django's documentation here, you would create ModelAdmins and register your models. Beyond that you can manage your users easily through the admin system, example code:
models.py
from django.contrib.auth.models import User
from django.db import models
class Teacher(models.Model):
user = models.ForeignKey(User, related_name='teacher')
class Student(models.Model):
user = models.ForeignKey(User, related_name='student')
admin.py
from django.contrib import admin
from .models import Teacher, Student
admin.site.register(Teacher)
admin.site.register(Student)
As for security, it is not clear what you mean by "use it as a security layer in my app", if you elaborate more, people can better help you. You can generally learn about security in django here.
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.
I'm trying to extend the default Django's authentication model with additional fields and functionaliy, so I've decided to just go with extending User model and writing my own authentication backend.
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User
class MyUser(User):
access_key = models.CharField(_('Acces Key'), max_length=64)
This is really a basic code yet when trying to syncdb I'm cetting a strange error that Google doesn't know about :
CommandError: One or more models did not validate:
core.sldcuser: 'user_ptr' defines a relation with the model 'auth.User', which has been swapped out. Update the relation to point at settings.AUTH_USER_MODEL.
In my settings.py I've added what I guess is required :
AUTH_USER_MODEL = 'core.MyUser'
Had anyone stumbled upon this error ?
Or maybe I should use a one-to-one way, or a hybrid of 1t1 with proxy ?
What you're doing right now, is creating a subclass of User, which is non-abstract. This means creating a table that has a ForeignKey called user_ptr pointing at the primary key on the auth.User table. However, what you're also doing by setting AUTH_USER_MODEL is telling django.contrib.auth not to create that table, because you'll be using MyUser instead. Django is understandably a little confused :P
What you need to do instead is inherit either from AbstractUser or AbstractBaseUser.
Use AbstractUser if you want everything that User has already, and just want to add more fields
Use AbstractBaseUser if you want to start from a clean state, and only inherit generic functions on the User, but implement your own fields.
REF:
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model
I want to add a convenience/model method to the django.contrib.auth.models.User model. What is the best practice for doing this since, last time I checked, extending the User model was considered bad practice.
I have a separate custom UserProfile model. Should I be using that for all User-related convenience methods?
It depends what you are trying to add to the model. If you want to add more information about the user, then it is generally recommended that you use the UserProfile method: http://docs.djangoproject.com/en/dev/topics/auth/#storing-additional-information-about-users
However, if you just want to add custom methods or managers to the User model, I would say that it's more logical to use a proxy model, like so:
from django.contrib.auth.models import User
class UserMethods(User):
def custom_method(self):
pass
class Meta:
proxy=True
A proxy model will operate on the same database table as the original model, so is ideal for creating custom methods without physically extending the model. Just replace any references to User in your views to UserMethods. (And of course you can use this in the admin tool by unregistering the User model and registering your proxy model in its stead.)
Any instances of the original User model that are created will be instantly accessible via the UserMethods model, and vice-versa. More here: http://docs.djangoproject.com/en/dev/topics/db/models/#proxy-models
(NB. Proxy models require Django 1.1 and above)
if you want to add custom methods to the User model, I would recommend monkey_patching:
create a file monkey_patching.py in any of your apps::
#app/monkey_patching.py
from django.contrib.auth.models import User
def get_user_name(self):
if self.first_name or self.last_name:
return self.first_name + " " + self.last_name
return self.username
User.add_to_class("get_user_name",get_user_name)
and import it in app's __init__.py file. ie::
#app/__init__.py
import monkey_patching
Yes. No need to mess with the foundations when your user model has a .get_profile() function attached to it.
2013 update:
in 1.5 you can sustitute a custom User model and add whatever you want https://docs.djangoproject.com/en/dev/topics/auth/customizing/#auth-custom-user
I prefer to use the same UserProfile across various projects I develop and extend User for any project-specific needs. So, common functionality goes to UserProfile, and project-specific functionality goes to custom User. I have not had any adverse effects of having a subclassed User model yet, I wonder if there still exist any with Django 1.0+.