mirror of
https://github.com/evennia/evennia.git
synced 2026-03-22 07:46:30 +01:00
Fix for typeclass app_label, and admin fix. Resolves #2112.
This commit is contained in:
parent
2e4f7e5744
commit
1e692d1bf5
2 changed files with 108 additions and 13 deletions
|
|
@ -4,13 +4,26 @@
|
|||
#
|
||||
from django import forms
|
||||
from django.conf import settings
|
||||
from django.contrib import admin
|
||||
from django.contrib import admin, messages
|
||||
from django.contrib.admin.options import IS_POPUP_VAR
|
||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||
from django.contrib.auth.forms import UserChangeForm, UserCreationForm
|
||||
from django.contrib.admin.utils import unquote
|
||||
from django.template.response import TemplateResponse
|
||||
from django.http import Http404, HttpResponseRedirect
|
||||
from django.core.exceptions import PermissionDenied
|
||||
from django.views.decorators.debug import sensitive_post_parameters
|
||||
from django.utils.decorators import method_decorator
|
||||
from django.utils.html import escape
|
||||
from django.urls import path, reverse
|
||||
from django.contrib.auth import update_session_auth_hash
|
||||
|
||||
from evennia.accounts.models import AccountDB
|
||||
from evennia.typeclasses.admin import AttributeInline, TagInline
|
||||
from evennia.utils import create
|
||||
|
||||
sensitive_post_parameters_m = method_decorator(sensitive_post_parameters())
|
||||
|
||||
|
||||
# handle the custom User editor
|
||||
class AccountDBChangeForm(UserChangeForm):
|
||||
|
|
@ -260,6 +273,71 @@ class AccountDBAdmin(BaseUserAdmin):
|
|||
),
|
||||
)
|
||||
|
||||
@sensitive_post_parameters_m
|
||||
def user_change_password(self, request, id, form_url=''):
|
||||
user = self.get_object(request, unquote(id))
|
||||
if not self.has_change_permission(request, user):
|
||||
raise PermissionDenied
|
||||
if user is None:
|
||||
raise Http404('%(name)s object with primary key %(key)r does not exist.') % {
|
||||
'name': self.model._meta.verbose_name,
|
||||
'key': escape(id),
|
||||
}
|
||||
if request.method == 'POST':
|
||||
form = self.change_password_form(user, request.POST)
|
||||
if form.is_valid():
|
||||
form.save()
|
||||
change_message = self.construct_change_message(request, form, None)
|
||||
self.log_change(request, user, change_message)
|
||||
msg = 'Password changed successfully.'
|
||||
messages.success(request, msg)
|
||||
update_session_auth_hash(request, form.user)
|
||||
return HttpResponseRedirect(
|
||||
reverse(
|
||||
'%s:%s_%s_change' % (
|
||||
self.admin_site.name,
|
||||
user._meta.app_label,
|
||||
# the model_name is something we need to hardcode
|
||||
# since our accountdb is a proxy:
|
||||
"accountdb",
|
||||
),
|
||||
args=(user.pk,),
|
||||
)
|
||||
)
|
||||
else:
|
||||
form = self.change_password_form(user)
|
||||
|
||||
fieldsets = [(None, {'fields': list(form.base_fields)})]
|
||||
adminForm = admin.helpers.AdminForm(form, fieldsets, {})
|
||||
|
||||
context = {
|
||||
'title': 'Change password: %s' % escape(user.get_username()),
|
||||
'adminForm': adminForm,
|
||||
'form_url': form_url,
|
||||
'form': form,
|
||||
'is_popup': (IS_POPUP_VAR in request.POST or
|
||||
IS_POPUP_VAR in request.GET),
|
||||
'add': True,
|
||||
'change': False,
|
||||
'has_delete_permission': False,
|
||||
'has_change_permission': True,
|
||||
'has_absolute_url': False,
|
||||
'opts': self.model._meta,
|
||||
'original': user,
|
||||
'save_as': False,
|
||||
'show_save': True,
|
||||
**self.admin_site.each_context(request),
|
||||
}
|
||||
|
||||
request.current_app = self.admin_site.name
|
||||
|
||||
return TemplateResponse(
|
||||
request,
|
||||
self.change_user_password_template or
|
||||
'admin/auth/user/change_password.html',
|
||||
context,
|
||||
)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
"""
|
||||
Custom save actions.
|
||||
|
|
|
|||
|
|
@ -104,18 +104,24 @@ class TypeclassBase(SharedMemoryModelBase):
|
|||
attrs["typename"] = name
|
||||
attrs["path"] = "%s.%s" % (attrs["__module__"], name)
|
||||
|
||||
# typeclass proxy setup
|
||||
app_label = None
|
||||
# first check explicit __applabel__ on the typeclass
|
||||
if "__applabel__" not in attrs:
|
||||
# find the app-label in one of the bases, usually the dbmodel
|
||||
def _get_dbmodel(bases):
|
||||
"""Recursively get the dbmodel"""
|
||||
if not hasattr(bases, "__iter__"):
|
||||
bases = [bases]
|
||||
for base in bases:
|
||||
try:
|
||||
attrs["__applabel__"] = base.__applabel__
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
break
|
||||
if base._meta.proxy or base._meta.abstract:
|
||||
for kls in base._meta.parents:
|
||||
return _get_dbmodel(kls)
|
||||
return base
|
||||
|
||||
dbmodel = _get_dbmodel(bases)
|
||||
|
||||
# typeclass proxy setup
|
||||
# first check explicit __applabel__ on the typeclass, then figure
|
||||
# it out from the dbmodel
|
||||
if dbmodel and "__applabel__" not in attrs:
|
||||
# find the app-label in one of the bases, usually the dbmodel
|
||||
attrs["__applabel__"] = dbmodel._meta.app_label
|
||||
|
||||
if "Meta" not in attrs:
|
||||
class Meta:
|
||||
|
|
@ -127,9 +133,20 @@ class TypeclassBase(SharedMemoryModelBase):
|
|||
|
||||
new_class = ModelBase.__new__(cls, name, bases, attrs)
|
||||
|
||||
# django doesn't support inheriting proxy models so we hack support for
|
||||
# it here by injecting `proxy_for_model` to the actual dbmodel.
|
||||
# Unfortunately we cannot also set the correct model_name, because this
|
||||
# would block multiple-inheritance of typeclasses (Django doesn't allow
|
||||
# multiple bases of the same model).
|
||||
if dbmodel:
|
||||
new_class._meta.proxy_for_model = dbmodel
|
||||
# Maybe Django will eventually handle this in the future:
|
||||
# new_class._meta.model_name = dbmodel._meta.model_name
|
||||
|
||||
# attach signals
|
||||
signals.post_save.connect(call_at_first_save, sender=new_class)
|
||||
signals.pre_delete.connect(remove_attributes_on_delete, sender=new_class)
|
||||
signals.pre_delete.connect(
|
||||
remove_attributes_on_delete, sender=new_class)
|
||||
return new_class
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue