Python Django Authentication Users and Authorization Checkpoints

Cristian Romero
Cristian Romero
11,910 Points

Django Authentication community_detail.html section

Hi everyone, not sure if this is happening just to me but for some reason I do not get the users to display in the member's box.

Here is my code:

URLS.PY

from django.conf.urls import url

from . import views

urlpatterns = [ url(r"^$", views.AllCommunities.as_view(), name="list"), url(r"^new/$", views.CreateCommunity.as_view(), name="create"), url( r"^posts/in/(?P<slug>[-\w]+)/$", views.SingleCommunity.as_view(), name="single" ), url( r"join/(?P<slug>[-\w]+)/$", views.JoinCommunity.as_view(), name="join" ), url( r"leave/(?P<slug>[-\w]+)/$", views.LeaveCommunity.as_view(), name="leave" ), url( r"change_status/(?P<slug>[-\w]+)/(?P<user_id>\d+)/(?P<status>\d)/$", views.ChangeStatus.as_view(), name="change_status" ), ]

from django.conf.urls import url

from . import views

urlpatterns = [ url(r"^$", views.AllCommunities.as_view(), name="list"), url(r"^new/$", views.CreateCommunity.as_view(), name="create"), url( r"^posts/in/(?P<slug>[-\w]+)/$", views.SingleCommunity.as_view(), name="single" ), url( r"join/(?P<slug>[-\w]+)/$", views.JoinCommunity.as_view(), name="join" ), url( r"leave/(?P<slug>[-\w]+)/$", views.LeaveCommunity.as_view(), name="leave" ), url( r"change_status/(?P<slug>[-\w]+)/(?P<user_id>\d+)/(?P<status>\d)/$", views.ChangeStatus.as_view(), name="change_status" ), ]

VIEWS.PY

from django.contrib import messages from django.contrib.auth.mixins import LoginRequiredMixin, PermissionRequiredMixin from django.contrib.auth.models import Group, Permission from django.core.urlresolvers import reverse from django.db import IntegrityError from django.shortcuts import get_object_or_404 from django.views import generic

from braces.views import PrefetchRelatedMixin

from . import models

class CreateCommunity(LoginRequiredMixin, generic.CreateView): fields = ("name", "description") model = models.Community

def form_valid(self, form):
    resp = super().form_valid(form)
    models.CommunityMember.objects.create(
        community=self.object,
        user=self.request.user,
        role=3
    )
    return resp

class SingleCommunity(PrefetchRelatedMixin, generic.DetailView): model = models.Community prefetch_related = ("members",)

class AllCommunities(generic.ListView): model = models.Community

class JoinCommunity(LoginRequiredMixin, generic.RedirectView): def get_redirect_url(self, *args, **kwargs): return reverse("communities:single", kwargs={"slug": self.kwargs.get("slug")})

def get(self, request, *args, **kwargs):
    community = get_object_or_404(models.Community,
                                  slug=self.kwargs.get("slug"))
    try:
        models.CommunityMember.objects.create(
            user=self.request.user,
            community=community,
            role=1
        )
    except IntegrityError:
        messages.warning(
            self.request,
            ("You were already a member of <b>{}</b>.  "
             "Don't be sneaky!").format(
                community.name
            )
        )
    else:
        messages.success(
            self.request,
            "You're now a member of <b>{}</b>!".format(community.name)
        )
    return super().get(request, *args, **kwargs)

class LeaveCommunity(LoginRequiredMixin, generic.RedirectView): def get_redirect_url(self, *args, **kwargs): return reverse("communities:single", kwargs={"slug": self.kwargs.get("slug")})

def get(self, request, *args, **kwargs):
    try:
        membership = models.CommunityMember.objects.filter(
            user=self.request.user,
            community__slug=self.kwargs.get("slug")
        ).exclude(role=3).get()
    except models.CommunityMember.DoesNotExist:
        messages.warning(
            self.request,
            "You can't leave this group."
        )
    else:
        membership.delete()
        messages.success(
            self.request,
            "You've left the group!"
        )
    return super().get(request, *args, **kwargs)

class ChangeStatus( LoginRequiredMixin, PermissionRequiredMixin, generic.RedirectView ): permission_required = "communities.ban_member"

def has_permission(self):
    return any([
            super().has_permission(),
            self.request.user.id in self.get_object().admins
    ])

def get_object(self):
    return get_object_or_404(
        models.Community,
        slug=self.kwargs.get("slug")
    )

def get_redirect_url(self, *args, **kwargs):
    return self.get_object().get_absolute_url()

def get(self, request, *args, **kwargs):
    role = int(self.kwargs.get("status"))
    membership = get_object_or_404(
        models.CommunityMember,
        community__slug=self.kwargs.get("slug"),
        user__id=self.kwargs.get("user_id")
    )
    membership.role = role
    membership.save()

    try:
        moderators = Group.objects.get(name__iexact="moderators")
    except Group.DoesNotExist:
        moderators = Group.objects.create(name="Moderators")
        moderators.permissions.add(
            Permissions.objects.get(codename="ban_members")
        )
    if role in [2, 3]:
        membership.user.groups.add(moderators)
    else:
        membership.user.groups.remove(moderators)

    messages.success(request, "@{} is now {}".format(
            membership.user.username,
            membership.get_role_display()
        ))

    return super().get(request, *args, **kwargs)

MODELS.PY

from django.conf import settings from django.core.urlresolvers import reverse from django.db import models from django.utils.text import slugify

import misaka

MEMBERSHIP_CHOICES = ( (0, "banned"), (1, "member"), (2, "moderator"), (3, "admin") )

class Community(models.Model): name = models.CharField(max_length=255, unique=True) slug = models.SlugField(allow_unicode=True, unique=True) description = models.TextField(blank=True, default='') description_html = models.TextField(editable=False, default='', blank=True) members = models.ManyToManyField(settings.AUTH_USER_MODEL, through="CommunityMember")

def __str__(self):
    return self.name

def save(self, *args, **kwargs):
    self.slug = slugify(self.name)
    self.description_html = misaka.html(self.description)
    super().save(*args, **kwargs)

def get_absolute_url(self):
    return reverse("communities:single", kwargs={"slug": self.slug})

@property
def admins(self):
    return self.memberships.filter(role=3).values_list("user", flat=True)

@property
def moderators(self):
    return self.memberships.filter(role=2).values_list("user", flat=True)

@property
def good_members(self):
    return self.memberships.filter(role=0)

class Meta:
    ordering = ["name"]
    verbose_name_plural = "communities"

class CommunityMember(models.Model): community = models.ForeignKey(Community, related_name="memberships") user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="communities") role = models.IntegerField(choices=MEMBERSHIP_CHOICES, default=1)

def __str__(self):
    return "{} is {} in {}".format(
        self.user.username,
        self.role,
        self.community.name
    )

class Meta:
    permissions = (
        ("ban_member", "Can ban members"),
    )
    unique_together = ("community", "user")

COMMUNITY_DETAIL.HTML

{% extends "communities/layout.html" %} {% load community_tags %}

{% block pre_community_content %} <div class="col-md-4"> <div class="card card-with-shadow"> <div class="content"> <h5 class="title">{{ community.name }}</h5> {{ community.description_html|safe }} {% community_buttons community %} </div> </div> <div class="card card-with-shadow"> <div class="content"> <h5 class="title">Members</h5> <ul class="list-unstyled"> {% for membership in community.good_members %} <li class="row"> <a href="{% url "posts:for_user" username=membership.user.username %}" class="col-md-9">{{ membership.user.display_name }}</a> <div class="col-md-3 text-right"> {% if user.id in community.admins or user.id in community.moderators %} {% if membership.user.id in community.moderators %} <a href="{% url 'communities:change_status' slug=community.slug user_id=membership.user.id status=1 %}"><i class="glyphicon glyphicon-thumbs-down text-warning"></i></a> {% endif %} {% if membership.user.id not in community.moderators and membership.user.id not in community.admins %} <a href="{% url 'communities:change_status' slug=community.slug user_id=membership.user.id status=2 %}"><i class="glyphicon glyphicon-thumbs-up text-warning"></i></a> {% endif %} {% if perms.communities.ban_member %} <a href="{% url 'communities:change_status' slug=community.slug user_id=membership.user.id status=0 %}"><i class="glyphicon glyphicon-ban-circle text-danger"></i></a> {% endif %} {% endif %} </div> </li> {% endfor %} </ul> </div> </div> </div> {% endblock %}

{% block community_content %} <div class="col-md-8"> {% for post in community.posts.all %} {% include "posts/_post.html" %} {% endfor %} </div> {% endblock %}