我刚刚在django中创建了一个名为Subscriber的自定义用户模型,它继承自AbstractBaseUser和PermissionsMixin。然后,我在admin.py文件中将必要的表单类子类化,以便使用管理控制台注册我的自定义用户模型。
首先,我对django中自定义用户模型和权限以及组如何组合起来有点困惑。在将PermissionsMixin传递给我的用户模型后,我运行了 manage.py migrate 脚本,并在我的数据库 subscriber_conf_subscriber_groups 和 subscriber_conf_subscriber_user_permissions 中创建了两个新表。另外,在django documentation中有一个例子,其中Group模型是从管理员注销的,所以我也是这样做的。
现在,在管理控制台中,我只有一个订阅者和表单列表,用于创建&编辑订阅者。我的问题是,如何添加从管理控制台为我的订阅者分配权限和组的功能?此时新用户模型是否仍然与内置的django权限和组相关联,或者这是我必须编写的内容吗?
任何澄清都会很棒。
models.py
from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from django.utils import timezone
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser, PermissionsMixin
#Custom user manager
class SubscriberManager(BaseUserManager):
def create_user(self, email, first_name, last_name, dti_id, street_address1,
street_address2, city, state, full_zip, phone_number, password=None):
#save 5 digit zip
tmp_zip = full_zip.split("-")
new_zip = tmp_zip[0]
return self._create_user(email, first_name, last_name, dti_id, street_address1,
street_address2, city, state, new_zip, full_zip, phone_number,
False, False, password, 0)
#utility function
def _create_user(self, email, first_name, last_name, dti_id, street_address1,
street_address2, city, state, zip_code, full_zip,
phone_number, is_superuser, is_staff, password=None, account_updated=0):
#define now
now = timezone.now()
if not email:
raise ValueError('Users must have an email address')
#use django to normalize the email address
email = self.normalize_email(email)
user = self.model(
email = email,
first_name = first_name,
last_name = last_name,
dti_id = dti_id,
street_address1 = street_address1,
street_address2 = street_address2,
city = city,
state = state,
zip_code = zip_code,
full_zip = full_zip,
phone_number = phone_number,
account_updated = account_updated,
is_admin = is_staff,
is_active = True,
is_superuser = is_superuser,
date_joined = now,
last_modified = now)
user.set_password(password)
user.save(using=self._db)
return user
#create superuser override
def create_superuser(self, email, first_name, last_name, dti_id, street_address1,
street_address2, city, state, full_zip, phone_number, password):
#either need to create needed fields or require them in user model
tmp_zip = full_zip.split("-")
new_zip = tmp_zip[0]
return self._create_user(email, first_name, last_name, dti_id, street_address1,
street_address2, city, state, new_zip, full_zip, phone_number,
True, True, password, 0)
#Custom user definition
class Subscriber(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(max_length=254, unique=True, db_index=True)
first_name = models.CharField(max_length=100)
last_name = models.CharField(max_length=100)
dti_id = models.IntegerField(default=0)
street_address1 = models.CharField(max_length=100)
street_address2 = models.CharField(max_length=100, blank=True)
city = models.CharField(max_length=100)
state = models.CharField(max_length=10)
zip_code = models.CharField(max_length=5)
full_zip = models.CharField(max_length=10, blank=True)
account_updated = models.BooleanField(default=0)
phone_number = models.CharField(max_length=20)
last_modified = models.DateTimeField(default=timezone.now)
date_joined = models.DateTimeField(default=timezone.now)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = SubscriberManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = [
'first_name',
'last_name',
'dti_id',
'street_address1',
'street_address2',
'city',
'state',
'full_zip',
'phone_number',
]
# define custom perms
class Meta:
permissions = (
("view_web", "Can access SJ web content"),
("view_web_e_edition", "Can access SJ e-edition content"),
("view_wweb", "Can access weekly web content"),
("view_wweb_e_edition", "Can access weekly e-edition content"),
#.... more permissions
#may be able to use this for subscriber coupons and such
)
def get_full_name(self):
return self.email
def get_short_name(self):
return self.email
def __unicode__(self):
return self.email
def has_perm(self, perm, obj=None):
return True
def has_module_perms(self, app_label):
return True
@property
def is_staff(self):
return self.is_admin
admin.py
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from subscriber_conf.models import Subscriber
class SubscriberCreationForm(forms.ModelForm):
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
class Meta:
model = Subscriber
fields = (
'email',
'first_name',
'last_name',
'dti_id',
'street_address1',
'street_address2',
'city',
'state',
'zip_code',
'full_zip',
'phone_number',
)
def clean_password2(self):
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
if password1 and password2 and password1 != password2:
raise forms.ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
user = super(SubscriberCreationForm, self).save(commit=False)
user.set_password(self.cleaned_data["password1"])
#perhaps do some stuff with times and dates
if commit:
user.save()
return user
class SubscriberChangeForm(forms.ModelForm):
password = ReadOnlyPasswordHashField()
class Meta:
model = Subscriber
fields = (
'email',
'password',
'first_name',
'last_name',
'dti_id',
'street_address1',
'street_address2',
'city',
'state',
'zip_code',
'full_zip',
'phone_number',
'account_updated',
'is_admin',
'is_active',
'is_superuser',
'date_joined',
'last_modified'
)
def clean_password(self):
return self.initial["password"]
class SubscriberAdmin(UserAdmin):
form = SubscriberChangeForm
add_form = SubscriberCreationForm
date_hierarchy = 'last_modified'
list_display = ('email', 'first_name', 'last_name',
'street_address1', 'street_address2', 'city', 'state',
'zip_code', 'full_zip', 'phone_number', 'dti_id', 'account_updated',
'last_modified', 'is_admin', 'is_superuser')
list_filter = ('is_admin', 'is_superuser', 'account_updated',)
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name', 'street_address1',
'street_address2', 'city', 'state', 'zip_code', 'full_zip',
'phone_number', 'account_updated',)}),
('Permissions', {'fields': ('is_admin',)}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'first_name', 'last_name', 'street_address1', 'street_address2',
'city', 'state', 'full_zip', 'phone_number', 'password1', 'password2')}
),
)
search_fields = ('email', 'street_address1', 'street_address2', 'first_name',
'last_name',)
ordering = ('dti_id',)
filter_horizontal = ()
admin.site.register(Subscriber, SubscriberAdmin)
admin.site.unregister(Group)
答案 0 :(得分:0)
有点晚了但是,对于其他人来说,试试这个
#admin.site.unregister(Group) <-- comment this line
和in fieldsets
('Permissions', {'fields': ('is_admin','is_staff','groups',)})
第一个可以管理来自Admin的组,第二个可以将组分配给新用户。我希望这有帮助! 问候!
答案 1 :(得分:-1)
在SubscriberAdmin类中,更改field_sets和add_fieldsets,如下所示。在权限中包含组。
fieldsets = (
(None, {'fields': ('name', 'password')}),
('Personal info', {'fields': ('email', 'phone', 'civilId', 'address',)}),
('Permissions', {'fields': ('groups',)}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('name', 'email', 'password1', 'password2', 'phone',
'civilId', 'address', 'groups',)}
),
('Permissions', {'fields': ('groups',)}),
)
在权限中包含组。还有一件事,如果你使用组,为什么取消注册组