Browse Source

#710: moved user profile views to class based views

Rafał Pitoń 8 years ago
parent
commit
7c33124f92

+ 7 - 7
misago/users/urls/__init__.py

@@ -44,13 +44,13 @@ urlpatterns += [
 
 urlpatterns += [
     url(r'^u/(?P<slug>[a-zA-Z0-9]+)/(?P<pk>\d+)/', include([
-        url(r'^$', profile.landing, name='user'),
-        url(r'^posts/$', profile.posts, name='user-posts'),
-        url(r'^threads/$', profile.threads, name='user-threads'),
-        url(r'^followers/$', profile.followers, name='user-followers'),
-        url(r'^follows/$', profile.follows, name='user-follows'),
-        url(r'^username-history/$', profile.username_history, name='username-history'),
-        url(r'^ban-details/$', profile.user_ban, name='user-ban'),
+        url(r'^$', profile.LandingView.as_view(), name='user'),
+        url(r'^posts/$', profile.UserPostsView.as_view(), name='user-posts'),
+        url(r'^threads/$', profile.UserThreadsView.as_view(), name='user-threads'),
+        url(r'^followers/$', profile.UserFollowersView.as_view(), name='user-followers'),
+        url(r'^follows/$', profile.UserFollowsView.as_view(), name='user-follows'),
+        url(r'^username-history/$', profile.UserUsernameHistoryView.as_view(), name='username-history'),
+        url(r'^ban-details/$', profile.UserBanView.as_view(), name='user-ban'),
     ]))
 ]
 

+ 1 - 2
misago/users/viewmodels/followers.py

@@ -7,8 +7,7 @@ from misago.users.serializers import UserCardSerializer
 
 class Followers(object):
     def __init__(self, request, profile, page=0, search=None):
-        queryset = self.get_queryset(profile).select_related(
-            'rank', 'ban_cache', 'online_tracker').order_by('slug')
+        queryset = self.get_queryset(profile).select_related('rank').order_by('slug')
 
         if not request.user.is_staff:
             queryset = queryset.filter(is_active=True)

+ 6 - 0
misago/users/viewmodels/follows.py

@@ -4,3 +4,9 @@ from .followers import Followers
 class Follows(Followers):
     def get_queryset(self, profile):
         return profile.follows
+
+    def get_template_context(self):
+        return {
+            'follows': self.users,
+            'count': self.paginator['count'],
+        }

+ 121 - 140
misago/users/views/profile.py

@@ -1,208 +1,189 @@
-from django.contrib import messages
 from django.contrib.auth import get_user_model
-from django.core.exceptions import PermissionDenied
-from django.db.transaction import atomic
-from django.http import Http404, JsonResponse
-from django.shortcuts import render as django_render
+from django.http import Http404
+from django.shortcuts import render
 from django.shortcuts import get_object_or_404, redirect
-from django.urls import reverse
 from django.utils import six
-from django.utils.translation import ugettext as _
+from django.views import View
 
 from misago.acl import add_acl
-from misago.conf import settings
-from misago.core.decorators import require_POST
 from misago.core.shortcuts import paginate, pagination_dict, validate_slug
-from misago.core.utils import clean_return_path
-from misago.threads.permissions import allow_message_user
 from misago.users.bans import get_user_ban
-from misago.users.decorators import deny_guests
 from misago.users.online.utils import get_user_status
 from misago.users.pages import user_profile
-from misago.users.permissions import allow_block_user, allow_follow_user
 from misago.users.serializers import (
-    BanDetailsSerializer, UserCardSerializer, UsernameChangeSerializer, UserSerializer)
+    BanDetailsSerializer, UsernameChangeSerializer, UserSerializer)
 from misago.users.viewmodels import Followers, Follows, UserPosts, UserThreads
 
 
 UserModel = get_user_model()
 
 
-def profile_view(f):
-    def decorator(request, *args, **kwargs):
-        relations = ('rank', 'online_tracker', 'ban_cache')
-        queryset = UserModel.objects.select_related(*relations)
+class ProfileView(View):
+    def get(self, request, *args, **kwargs):
+        profile = self.get_profile(request, kwargs.pop('pk'), kwargs.pop('slug'))
 
-        profile = get_object_or_404(queryset, pk=kwargs.pop('pk'))
+        # resolve that we can display requested section
+        sections = user_profile.get_sections(request, profile)
+        active_section = self.get_active_section(sections)
 
-        if not profile.is_active and not request.user.is_staff:
+        if not active_section:
             raise Http404()
 
-        validate_slug(profile, kwargs.pop('slug'))
-        kwargs['profile'] = profile
-
-        add_acl(request.user, profile)
+        profile.status = get_user_status(request.user, profile)
+        context_data = self.get_context_data(request, profile)
 
-        return f(request, *args, **kwargs)
-    return decorator
+        self.complete_frontend_context(request, profile, sections)
+        self.complete_context_data(request, profile, sections, context_data)
 
+        return render(request, self.template_name, context_data)
 
-def profile_view_restricted_visibility(f):
-    @profile_view
-    def decorator(request, *args, **kwargs):
-        sections = user_profile.get_sections(request, kwargs['profile'])
-        for section in sections:
-            if section['is_active']:
-                return f(request, *args, **kwargs)
-        else:
-            # we are trying to display page thats not in nav
-            raise Http404()
-    return decorator
-
+    def get_profile(self, request, pk, slug):
+        queryset = UserModel.objects.select_related(
+            'rank', 'online_tracker', 'ban_cache')
 
-def render(request, template, context):
-    request.frontend_context['PROFILE_PAGES'] = []
+        profile = get_object_or_404(queryset, pk=pk)
 
-    context['sections'] = user_profile.get_sections(request, context['profile'])
+        if not profile.is_active and not request.user.is_staff:
+            raise Http404()
 
-    for section in context['sections']:
-        request.frontend_context['PROFILE_PAGES'].append({
-            'name': six.text_type(section['name']),
-            'icon': section['icon'],
-            'meta': section.get('metadata'),
-            'component': section['component'],
-        })
+        validate_slug(profile, slug)
+        add_acl(request.user, profile)
 
-        if section['is_active']:
-            context['active_section'] = section
+        return profile
 
-    if request.user.is_authenticated:
-        is_authenticated_user = context['profile'].pk == request.user.pk
-    else:
-        is_authenticated_user = False
-    context['is_authenticated_user'] = is_authenticated_user
+    def get_active_section(self, sections):
+        for section in sections:
+            if section['is_active']:
+                return section
 
-    if request.user.is_authenticated:
-        if is_authenticated_user:
-            context['show_email'] = True
-        else:
-            context['show_email'] = request.user.acl['can_see_users_emails']
-    else:
-        context['show_email'] = False
+    def get_context_data(self, request, profile):
+        return {}
 
-    context['profile'].status = get_user_status(request.user, context['profile'])
+    def complete_frontend_context(self, request, profile, sections):
+        request.frontend_context['PROFILE_PAGES'] = []
+        for section in sections:
+            request.frontend_context['PROFILE_PAGES'].append({
+                'name': six.text_type(section['name']),
+                'icon': section['icon'],
+                'meta': section.get('metadata'),
+                'component': section['component'],
+            })
 
-    request.frontend_context['PROFILE'] = UserProfileSerializer(
-        context['profile'], context={'user': request.user}).data
+        request.frontend_context['PROFILE'] = UserProfileSerializer(
+            profile, context={'user': request.user}).data
 
-    if not context['profile'].is_active:
-        request.frontend_context['PROFILE']['is_active'] = False
+        if not profile.is_active:
+            request.frontend_context['PROFILE']['is_active'] = False
 
-    return django_render(request, template, context)
+    def complete_context_data(self, request, profile, sections, context):
+        context['profile'] = profile
 
+        context['sections'] = sections
+        for section in sections:
+            if section['is_active']:
+                context['active_section'] = section
+                break
+
+        if request.user.is_authenticated:
+            is_authenticated_user = profile.pk == request.user.pk
+            context.update({
+                'is_authenticated_user': is_authenticated_user,
+                'show_email': is_authenticated_user,
+            })
+
+            if not context['show_email']:
+                context['show_email'] = request.user.acl['can_see_users_emails']
+        else:
+            context.update({
+                'is_authenticated_user': False,
+                'show_email': False,
+            })
 
-@profile_view
-def landing(request, profile):
-    return redirect(user_profile.get_default_link(), slug=profile.slug, pk=profile.pk)
 
+class LandingView(ProfileView):
+    def get(self, request, *args, **kwargs):
+        profile = self.get_profile(request, kwargs.pop('pk'), kwargs.pop('slug'))
 
-@profile_view
-def posts(request, profile):
-    context = {
-        'profile': profile,
-    }
+        return redirect(
+            user_profile.get_default_link(),
+            slug=profile.slug,
+            pk=profile.pk
+        )
 
-    feed = UserPosts(request, profile)
-    context.update(feed.get_template_context())
 
-    request.frontend_context['POSTS'] = feed.get_frontend_context()
+class UserPostsView(ProfileView):
+    template_name = 'misago/profile/posts.html'
 
-    return render(request, 'misago/profile/posts.html', context)
+    def get_context_data(self, request, profile):
+        feed = UserPosts(request, profile)
 
+        request.frontend_context['POSTS'] = feed.get_frontend_context()
+        return feed.get_template_context()
 
-@profile_view
-def threads(request, profile):
-    context = {
-        'profile': profile
-    }
 
-    feed = UserThreads(request, profile)
-    context.update(feed.get_template_context())
+class UserThreadsView(ProfileView):
+    template_name = 'misago/profile/threads.html'
 
-    request.frontend_context['POSTS'] = feed.get_frontend_context()
+    def get_context_data(self, request, profile):
+        feed = UserThreads(request, profile)
 
-    return render(request, 'misago/profile/threads.html', context)
+        request.frontend_context['POSTS'] = feed.get_frontend_context()
+        return feed.get_template_context()
 
 
-@profile_view
-def followers(request, profile):
-    queryset = profile.followed_by.select_related('rank').order_by('slug')
+class UserFollowersView(ProfileView):
+    template_name = 'misago/profile/followers.html'
 
-    page = paginate(queryset, None, 12, 4)
-    paginator = pagination_dict(page)
+    def get_context_data(self, request, profile):
+        users = Followers(request, profile)
 
-    request.frontend_context['PROFILE_FOLLOWERS'] = dict(
-        results=UserCardSerializer(page.object_list, many=True).data,
-        **paginator
-    )
+        request.frontend_context['PROFILE_FOLLOWERS'] = users.get_frontend_context()
+        return users.get_template_context()
 
-    return render(request, 'misago/profile/followers.html', {
-        'profile': profile,
-        'followers': page.object_list,
-        'count': paginator['count'],
-    })
 
+class UserFollowsView(ProfileView):
+    template_name = 'misago/profile/follows.html'
 
-@profile_view
-def follows(request, profile):
-    queryset = profile.follows.select_related('rank').order_by('slug')
+    def get_context_data(self, request, profile):
+        users = Follows(request, profile)
 
-    page = paginate(queryset, None, settings.MISAGO_USERS_PER_PAGE, 4)
-    paginator = pagination_dict(page)
+        request.frontend_context['PROFILE_FOLLOWS'] = users.get_frontend_context()
+        return users.get_template_context()
 
-    request.frontend_context['PROFILE_FOLLOWS'] = dict(
-        results=UserCardSerializer(page.object_list, many=True).data,
-        **paginator
-    )
 
-    return render(request, 'misago/profile/follows.html', {
-        'profile': profile,
-        'follows': page.object_list,
-        'count': paginator['count'],
-    })
+class UserUsernameHistoryView(ProfileView):
+    template_name = 'misago/profile/username_history.html'
 
+    def get_context_data(self, request, profile):
+        queryset = profile.namechanges.select_related('user', 'changed_by')
+        queryset = queryset.order_by('-id')
 
-@profile_view_restricted_visibility
-def username_history(request, profile):
-    queryset = profile.namechanges.select_related('user', 'changed_by')
-    queryset = queryset.order_by('-id')
+        page = paginate(queryset, None, 14, 4)
 
-    page = paginate(queryset, None, 14, 4)
+        data = pagination_dict(page)
+        data.update({
+            'results': UsernameChangeSerializer(page.object_list, many=True).data
+        })
 
-    data = pagination_dict(page)
-    data.update({
-        'results': UsernameChangeSerializer(page.object_list, many=True).data
-    })
+        request.frontend_context['PROFILE_NAME_HISTORY'] = data
 
-    request.frontend_context['PROFILE_NAME_HISTORY'] = data
+        return {
+            'history': page.object_list,
+            'count': data['count'],
+        }
 
-    return render(request, 'misago/profile/username_history.html', {
-        'profile': profile,
-        'history': page.object_list,
-        'count': data['count'],
-    })
 
+class UserBanView(ProfileView):
+    template_name = 'misago/profile/ban_details.html'
 
-@profile_view_restricted_visibility
-def user_ban(request, profile):
-    ban = get_user_ban(profile)
+    def get_context_data(self, request, profile):
+        ban = get_user_ban(profile)
 
-    request.frontend_context['PROFILE_BAN'] = BanDetailsSerializer(ban).data
+        request.frontend_context['PROFILE_BAN'] = BanDetailsSerializer(ban).data
 
-    return render(request, 'misago/profile/ban_details.html', {
-        'profile': profile,
-        'ban': ban,
-    })
+        return {
+            'ban': ban,
+        }
 
 
 UserProfileSerializer = UserSerializer.subset_fields(