Browse Source

[fix] Separate change form to fix admin error

ljf 7 years ago
parent
commit
09e334c1ab
3 changed files with 64 additions and 19 deletions
  1. 2 2
      coin/members/admin.py
  2. 54 14
      coin/members/forms.py
  3. 8 3
      coin/members/views.py

+ 2 - 2
coin/members/admin.py

@@ -15,7 +15,7 @@ from django.utils.html import format_html
 from coin.members.models import (
     Member, CryptoKey, LdapUser, MembershipFee, OfferSubscription)
 from coin.members.membershipfee_filter import MembershipFeeFilter
-from coin.members.forms import MemberChangeForm, MemberCreationForm
+from coin.members.forms import AdminMemberChangeForm, MemberCreationForm
 from coin.utils import delete_selected
 import autocomplete_light
 
@@ -65,7 +65,7 @@ class MemberAdmin(UserAdmin):
     actions = [delete_selected, 'set_as_member', 'set_as_non_member',
                'bulk_send_welcome_email', 'bulk_send_call_for_membership_fee_email']
 
-    form = MemberChangeForm
+    form = AdminMemberChangeForm
     add_form = MemberCreationForm
 
     fieldsets = (

+ 54 - 14
coin/members/forms.py

@@ -3,6 +3,7 @@ from __future__ import unicode_literals
 
 from django import forms
 from django.contrib.auth.forms import PasswordResetForm, ReadOnlyPasswordHashField
+from django.forms.utils import ErrorList
 
 from coin.members.models import Member
 
@@ -37,28 +38,21 @@ class MemberCreationForm(forms.ModelForm):
         return member
 
 
-class MemberChangeForm(forms.ModelForm):
+class AbstractMemberChangeForm(forms.ModelForm):
+    """
+    This form was inspired from django.contrib.auth.forms.UserChangeForm
+    and adapted to coin specificities
+    """
 
     class Meta:
         model = Member
-        fields = ['first_name', 'last_name', 'email', 'nickname',
-        'organization_name', 'home_phone_number', 'mobile_phone_number',
-        'address', 'postal_code', 'city', 'country']
+        fields = '__all__'
 
     def __init__(self, *args, **kwargs):
-        super(MemberChangeForm, self).__init__(*args, **kwargs)
+        super(AbstractMemberChangeForm, self).__init__(*args, **kwargs)
         f = self.fields.get('user_permissions', None)
         if f is not None:
             f.queryset = f.queryset.select_related('content_type')
-        instance = getattr(self, 'instance', None)
-        if instance and instance.pk:
-            if instance.type == "natural_person":
-                del self.fields['organization_name']
-            else:
-                del self.fields['first_name']
-                del self.fields['last_name']
-        for fieldname in self.fields:
-            self.fields[fieldname].help_text = None
 
     def clean_password(self):
         # Regardless of what the user provides, return the initial value.
@@ -71,6 +65,52 @@ class MemberChangeForm(forms.ModelForm):
         return self.initial["username"]
 
 
+class AdminMemberChangeForm(AbstractMemberChangeForm):
+    password = ReadOnlyPasswordHashField()
+
+
+class SpanError(ErrorList):
+    def __unicode__(self):
+        return self.as_spans()
+    def __str__(self):
+        return self.as_spans()
+    def as_spans(self):
+        if not self: return ''
+        return ''.join(['<span class="error">%s</span>' % e for e in self])
+
+class PersonMemberChangeForm(AbstractMemberChangeForm):
+    """
+    Form use to allow natural person to change their info
+    """
+    class Meta:
+        model = Member
+        fields = ['first_name', 'last_name', 'email', 'nickname',
+                  'home_phone_number', 'mobile_phone_number',
+                  'address', 'postal_code', 'city', 'country']
+
+    def __init__(self, *args, **kwargs):
+        super(PersonMemberChangeForm, self).__init__(*args, **kwargs)
+        self.error_class = SpanError
+        for fieldname in self.fields:
+            self.fields[fieldname].help_text = None
+
+
+class OrganizationMemberChangeForm(AbstractMemberChangeForm):
+    """
+    Form use to allow organization to change their info
+    """
+    class Meta:
+        model = Member
+        fields = ['organization_name', 'email', 'nickname',
+                  'home_phone_number', 'mobile_phone_number',
+                  'address', 'postal_code', 'city', 'country']
+
+    def __init__(self, *args, **kwargs):
+        super(OrganizationChangeForm, self).__init__(*args, **kwargs)
+        self.error_class = SpanError
+        for fieldname in self.fields:
+            self.fields[fieldname].help_text = None
+
 class MemberPasswordResetForm(PasswordResetForm):
     pass
 

+ 8 - 3
coin/members/views.py

@@ -6,7 +6,7 @@ from django.shortcuts import render_to_response
 from django.contrib.auth.decorators import login_required
 from django.http import Http404
 from django.conf import settings
-from forms import MemberChangeForm
+from forms import PersonMemberChangeForm, OrganizationMemberChangeForm
 
 @login_required
 def index(request):
@@ -25,12 +25,17 @@ def detail(request):
     }
 
     if settings.MEMBER_CAN_EDIT_PROFILE:
+        if request.user.type == "natural_person":
+            form_cls = PersonMemberChangeForm
+        else:
+            form_cls = OrganizationMemberChangeForm
+
         if request.method == "POST":
-            form = MemberChangeForm(data = request.POST, instance = request.user)
+            form = form_cls(data = request.POST, instance = request.user)
             if form.is_valid():
                 form.save()
         else:
-            form = MemberChangeForm(instance = request.user)
+            form = form_cls(instance = request.user)
 
         context['form'] = form