Browse Source

#865: renamed profile extensions to profile fields, dropped form inheritance as primary mechanics

Rafał Pitoń 8 years ago
parent
commit
ff97453644

+ 26 - 3
misago/users/forms/admin.py

@@ -10,7 +10,6 @@ from misago.core import threadstore
 from misago.core.forms import IsoDateTimeField, YesNoSwitch
 from misago.core.forms import IsoDateTimeField, YesNoSwitch
 from misago.core.validators import validate_sluggable
 from misago.core.validators import validate_sluggable
 from misago.users.models import Ban, Rank
 from misago.users.models import Ban, Rank
-from misago.users.profilefields import profilefields
 from misago.users.validators import validate_email, validate_username
 from misago.users.validators import validate_email, validate_username
 
 
 
 
@@ -188,6 +187,28 @@ class EditUserForm(UserBaseForm):
             'subscribe_to_replied_threads',
             'subscribe_to_replied_threads',
         ]
         ]
 
 
+    def __init__(self, *args, **kwargs):
+        self.profilefields = kwargs.pop('profilefields')
+        self._profile_fields_groups = []
+
+        super(EditUserForm, self).__init__(*args, **kwargs)
+
+        self.profilefields.update_admin_form(self)
+
+    def get_profile_fields_groups(self):
+        profile_fields_groups = []
+        for group in self._profile_fields_groups:
+            fields_group = {
+                'name': group['name'],
+                'fields': [],
+            }
+
+            for fieldname in group['fields']:
+                fields_group['fields'].append(self[fieldname])
+
+            profile_fields_groups.append(fields_group)
+        return profile_fields_groups
+
     def clean_signature(self):
     def clean_signature(self):
         data = self.cleaned_data['signature']
         data = self.cleaned_data['signature']
 
 
@@ -203,6 +224,10 @@ class EditUserForm(UserBaseForm):
 
 
         return data
         return data
 
 
+    def clean(self):
+        data = super(EditUserForm, self).clean()
+        return self.profilefields.clean_admin_form(self, data)
+
 
 
 def UserFormFactory(FormType, instance):
 def UserFormFactory(FormType, instance):
     extra_fields = {}
     extra_fields = {}
@@ -275,8 +300,6 @@ def EditUserFormFactory(FormType, instance, add_is_active_fields=False, add_admi
     if add_admin_fields:
     if add_admin_fields:
         FormType = StaffFlagUserFormFactory(FormType, instance)
         FormType = StaffFlagUserFormFactory(FormType, instance)
 
 
-    FormType = profilefields.extend_admin_form(FormType, instance)
-
     return FormType
     return FormType
 
 
 
 

+ 19 - 36
misago/users/profilefields/__init__.py

@@ -2,7 +2,7 @@ from django.utils.module_loading import import_string
 
 
 from misago.conf import settings
 from misago.conf import settings
 
 
-from .base import ProfileField, TextProfileField
+from .base import ProfileField, TextProfileField, TextareaProfileField
 
 
 
 
 class ProfileFields(object):
 class ProfileFields(object):
@@ -36,16 +36,11 @@ class ProfileFields(object):
                             dict_from_map[field.fieldname]._field_path,
                             dict_from_map[field.fieldname]._field_path,
                         )
                         )
                     )
                     )
-                self.fields_dict[field_path] = field
+                self.fields_dict[field_path] = field()
 
 
         self.is_loaded = True
         self.is_loaded = True
 
 
-    def extend_admin_form(self, form, user):
-        class ProfileFieldsForm(form, ProfileFieldsMixin):
-            profile_fields_groups = []
-
-        new_form = ProfileFieldsForm
-
+    def update_admin_form(self, form):
         if not self.is_loaded:
         if not self.is_loaded:
             self.load()
             self.load()
 
 
@@ -56,34 +51,22 @@ class ProfileFields(object):
             }
             }
 
 
             for field_path in group['fields']:
             for field_path in group['fields']:
-                old_form = new_form
-
-                field = self.fields_dict[field_path]()
-                new_form = field.extend_admin_form(old_form, user)
-
-                if new_form != old_form:
-                   group_dict['fields'].append(field.fieldname)
-
-            if group_dict['fields']:
-                new_form.profile_fields_groups.append(group_dict)
-
-        return new_form
-
-
-class ProfileFieldsMixin(object):
-    def get_profile_fields_groups(self):
-        profile_fields_groups = []
-        for group in self.profile_fields_groups:
-            fields_group = {
-                'name': group['name'],
-                'fields': [],
-            }
-
-            for fieldname in group['fields']:
-                fields_group['fields'].append(self[fieldname])
-
-            profile_fields_groups.append(fields_group)
-        return profile_fields_groups
+                field = self.fields_dict[field_path]
+                admin_field = field.get_admin_field(form.instance)
+                if admin_field:
+                    form.fields[field.fieldname] = admin_field
+                    group_dict['fields'].append(field.fieldname)
+
+            form._profile_fields_groups.append(group_dict)
+
+    def clean_admin_form(self, form, data):
+        for field in self.fields_dict.values():
+            data = field.clean_admin_form(form, data) or data
+        return data
+
+    def admin_update_extra(self, user, cleaned_data):
+        for field in self.fields_dict.values():
+            field.admin_update_extra(user, cleaned_data)
 
 
 
 
 profilefields = ProfileFields(settings.MISAGO_PROFILE_FIELDS)
 profilefields = ProfileFields(settings.MISAGO_PROFILE_FIELDS)

+ 23 - 22
misago/users/profilefields/base.py

@@ -7,6 +7,7 @@ class ProfileField(object):
     """
     """
     fieldname = None
     fieldname = None
     label = None
     label = None
+    readonly = False
 
 
     def get_label(self, user):
     def get_label(self, user):
         if not self.label:
         if not self.label:
@@ -16,36 +17,36 @@ class ProfileField(object):
             )
             )
         return self.label
         return self.label
 
 
-    def extend_admin_form(self, form, user):
-        return form
+    def get_admin_field(self, user):
+        return None
 
 
+    def clean_admin_form(self, form, data):
+        return data
 
 
-class TextProfileField(ProfileField):
-    def extend_admin_form(self, form, user):
-        fieldname = self.fieldname
+    def admin_update_extra(self, user, cleaned_data):
+        if self.readonly:
+            return
+        user.extra[self.fieldname] = cleaned_data.get(self.fieldname)
 
 
-        return type('TextProfileFieldForm', (form,), {
-            fieldname: self.get_admin_form_field(
-                user, fieldname, self.get_label(user)),
-            'clean_{}'.format(fieldname): self.get_admin_form_field_clean(
-                user, fieldname),
-        })
 
 
-    def get_admin_form_field(self, user, fieldname, label):
+class TextProfileField(ProfileField):
+    def get_admin_field(self, user):
         return forms.CharField(
         return forms.CharField(
-            label=label,
-            initial=user.extra.get(fieldname),
+            label=self.get_label(user),
+            initial=user.extra.get(self.fieldname),
             max_length=250,
             max_length=250,
             required=False,
             required=False,
         )
         )
 
 
-    def get_admin_form_field_clean(self, user, fieldname):
-        def clean_field(self):
-            data = self.cleaned_data.get(fieldname)
-            user.extra[fieldname] = data
-            return data
-        return clean_field
-
 
 
 class TextareaProfileField(TextProfileField):
 class TextareaProfileField(TextProfileField):
-    pass
+    def get_admin_field(self, user):
+        return forms.CharField(
+            label=self.get_label(user),
+            initial=user.extra.get(self.fieldname),
+            max_length=250,
+            widget=forms.Textarea(
+                attrs={'rows': 4},
+            ),
+            required=False,
+        )

+ 18 - 0
misago/users/profilefields/default.py

@@ -0,0 +1,18 @@
+from django.utils.translation import ugettext_lazy as _
+
+from . import TextProfileField, TextareaProfileField
+
+
+class BioField(TextareaProfileField):
+    fieldname = 'bio'
+    label = _("Bio")
+
+
+class FullNameField(TextProfileField):
+    fieldname = 'fullname'
+    label = _("Full name")
+
+
+class LocationField(TextProfileField):
+    fieldname = 'location'
+    label = _("Location")

+ 0 - 8
misago/users/profilefields/fullname.py

@@ -1,8 +0,0 @@
-from django.utils.translation import ugettext_lazy as _
-
-from . import TextProfileField
-
-
-class FullNameField(TextProfileField):
-    fieldname = 'fullname'
-    label = _("Full name")

+ 14 - 0
misago/users/views/admin/users.py

@@ -16,6 +16,7 @@ from misago.users.avatars.dynamic import set_avatar as set_dynamic_avatar
 from misago.users.forms.admin import (
 from misago.users.forms.admin import (
     BanUsersForm, EditUserForm, EditUserFormFactory, NewUserForm, SearchUsersForm)
     BanUsersForm, EditUserForm, EditUserFormFactory, NewUserForm, SearchUsersForm)
 from misago.users.models import Ban
 from misago.users.models import Ban
+from misago.users.profilefields import profilefields
 from misago.users.signatures import set_user_signature
 from misago.users.signatures import set_user_signature
 
 
 
 
@@ -263,6 +264,17 @@ class EditUser(UserAdmin, generic.ModelFormView):
         target.old_is_avatar_locked = target.is_avatar_locked
         target.old_is_avatar_locked = target.is_avatar_locked
         return super(EditUser, self).real_dispatch(request, target)
         return super(EditUser, self).real_dispatch(request, target)
 
 
+    def initialize_form(self, form, request, target):
+        if request.method == 'POST':
+            return form(
+                request.POST,
+                request.FILES,
+                instance=target,
+                profilefields=profilefields,
+            )
+        else:
+            return form(instance=target, profilefields=profilefields)
+
     def handle_form(self, form, request, target):
     def handle_form(self, form, request, target):
         target.username = target.old_username
         target.username = target.old_username
         if target.username != form.cleaned_data.get('username'):
         if target.username != form.cleaned_data.get('username'):
@@ -299,6 +311,8 @@ class EditUser(UserAdmin, generic.ModelFormView):
 
 
         set_user_signature(request, target, form.cleaned_data.get('signature'))
         set_user_signature(request, target, form.cleaned_data.get('signature'))
 
 
+        profilefields.admin_update_extra(target, form.cleaned_data)
+
         target.update_acl_key()
         target.update_acl_key()
         target.save()
         target.save()