merged
This commit is contained in:
@@ -5,11 +5,11 @@ from django.utils.text import slugify
|
||||
import urllib.parse
|
||||
t = datetime.now() + timedelta(days=1)
|
||||
|
||||
|
||||
from .etherpadlib import get_ep_sessionid2, add_ep_cookie
|
||||
|
||||
SERVER_URL="https://etherpad2.2020.fet.at/"
|
||||
|
||||
|
||||
SERVER_URL = "https://etherpad2.2020.fet.at/"
|
||||
|
||||
with open("/srv/andis_test/etherpad_test2/etherpad-lite/APIKEY.txt", "r") as f:
|
||||
k = f.read()
|
||||
|
||||
@@ -13,7 +13,9 @@ class FETHeaderMiddleware(RemoteUserMiddleware):
|
||||
self.header,
|
||||
request.headers.get(self.header, None)
|
||||
)
|
||||
# logger = logging.getLogger(__name__)
|
||||
super().process_request(request)
|
||||
# logger.info('User: ' + str(request.user))
|
||||
if request.user.is_authenticated:
|
||||
request.user.is_admin = True
|
||||
request.user.is_superuser = True
|
||||
|
||||
@@ -116,6 +116,7 @@ DATABASES = {
|
||||
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
'django.contrib.auth.backends.RemoteUserBackend',
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
]
|
||||
|
||||
# Password validation
|
||||
|
||||
@@ -20,7 +20,7 @@ def index(request):
|
||||
|
||||
context = {
|
||||
'posts': posts,
|
||||
'events': Event.objects.order_by("-event_start").all(),
|
||||
'events': Event.objects.get_all_events(),
|
||||
'featured_post': featured_post,
|
||||
'featured_post2': FetMeeting.objects.first(),
|
||||
'tags_list': ", ".join(t)
|
||||
|
||||
@@ -54,12 +54,41 @@ class JobInline(admin.TabularInline):
|
||||
class MyMemberAdmin(admin.ModelAdmin):
|
||||
form = MyMemberForm
|
||||
model = Member
|
||||
fieldsets = (
|
||||
(None, {
|
||||
'fields': (
|
||||
('firstname', 'surname',),
|
||||
'nickname',
|
||||
'mailaccount',
|
||||
'role',
|
||||
'description',
|
||||
'image',
|
||||
'birthday',
|
||||
'phone',
|
||||
'address',
|
||||
)
|
||||
}),
|
||||
)
|
||||
list_display = ['nickname', 'firstname', 'surname', 'mailaccount', 'role']
|
||||
inlines = (JobOverviewInline,)
|
||||
|
||||
search_fields = ['firstname', 'surname', 'nickname', 'mailaccount']
|
||||
list_filter = [MemberRoleFilter]
|
||||
|
||||
def add_view(self, request, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
return super().add_view(
|
||||
request, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
return super().change_view(
|
||||
request, object_id, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.author = request.user
|
||||
super().save_model(request, obj, form, change)
|
||||
@@ -76,6 +105,20 @@ class MyJobAdmin(admin.ModelAdmin):
|
||||
|
||||
search_fields = ['name']
|
||||
|
||||
def add_view(self, request, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
return super().add_view(
|
||||
request, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichfelder."
|
||||
return super().change_view(
|
||||
request, object_id, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.author = request.user
|
||||
super().save_model(request, obj, form, change)
|
||||
@@ -92,6 +135,20 @@ class MyJobGroupAdmin(admin.ModelAdmin):
|
||||
|
||||
search_fields = ['name']
|
||||
|
||||
def add_view(self, request, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
return super().add_view(
|
||||
request, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichfelder."
|
||||
return super().change_view(
|
||||
request, object_id, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.author = request.user
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
from django.core.validators import RegexValidator
|
||||
from django.core.validators import RegexValidator, ValidationError
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.utils import timezone
|
||||
@@ -6,6 +6,7 @@ from django.utils.text import slugify
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from datetime import timedelta
|
||||
from easy_thumbnails.fields import ThumbnailerImageField
|
||||
from rest_framework import serializers
|
||||
|
||||
|
||||
@@ -91,7 +92,7 @@ class Member(models.Model):
|
||||
role = models.CharField(max_length=1, choices=MemberRole.choices, default=MemberRole.ACTIVE)
|
||||
|
||||
description = models.TextField(null=True, blank=True)
|
||||
image = models.ImageField(null=True, blank=True)
|
||||
image = ThumbnailerImageField()
|
||||
|
||||
birthday = models.DateField(null=True, blank=True)
|
||||
|
||||
@@ -113,6 +114,15 @@ class Member(models.Model):
|
||||
verbose_name = "Mitglied"
|
||||
verbose_name_plural = "Mitglieder"
|
||||
|
||||
def clean(self):
|
||||
if self.image.height < 150 or self.image.width < 150:
|
||||
raise ValidationError(
|
||||
_('Das Bild ist zu klein. (Höhe: {}, Breite: {})').format(
|
||||
self.image.height,
|
||||
self.image.width
|
||||
)
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return self.firstname + " " + self.surname
|
||||
|
||||
@@ -139,6 +149,10 @@ class JobGroup(models.Model):
|
||||
|
||||
is_pinned = models.BooleanField(default=False)
|
||||
|
||||
class Meta:
|
||||
verbose_name = "Tätigkeit-Gruppierung"
|
||||
verbose_name_plural = "Tätigkeit-Gruppierungen"
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('', views.index, name='members'),
|
||||
path('<str:filter>', views.index),
|
||||
path('jobs/<str:slug>', views.index),
|
||||
path('m/<str:nickname>',views.show, name="member")
|
||||
|
||||
path('<str:filter>', views.members_view),
|
||||
path('jobs/<str:slug>', views.jobs_view),
|
||||
path('member/<str:member_name>', views.profile_view, name="member"),
|
||||
]
|
||||
@@ -10,39 +10,81 @@ from rest_framework import permissions
|
||||
# from django_filters.rest_framework import DjangoFilterBackend
|
||||
|
||||
|
||||
<<<<<<< HEAD
|
||||
def show(request,nickname=None):
|
||||
return render(request, 'members/index.html', context)
|
||||
|
||||
|
||||
def index(request, slug=None, filter=None):
|
||||
job_group = deque(JobGroup.objects.all())
|
||||
job_list = []
|
||||
members = None
|
||||
|
||||
if slug is not None:
|
||||
job_names = JobMember.jobs.get_job_names(slug=slug)
|
||||
active_members = JobMember.active_member.get_members_of_job(job_names=job_names)
|
||||
inactive_members = JobMember.inactive_member.get_members_of_job(job_names=job_names)
|
||||
|
||||
for idx, item in enumerate(job_names):
|
||||
job_list.append((job_names[idx], active_members[idx], inactive_members[idx]))
|
||||
if filter is None:
|
||||
members = deque(Member.all_members.all())
|
||||
elif filter in Member.MemberRole:
|
||||
members = deque(Member.all_members.filter(role=filter))
|
||||
else:
|
||||
if filter is None:
|
||||
members = deque(Member.all_members.all())
|
||||
elif filter in Member.MemberRole:
|
||||
members = deque(Member.all_members.filter(role=filter))
|
||||
else:
|
||||
members = None
|
||||
members = None
|
||||
|
||||
context = {
|
||||
"job_group": job_group,
|
||||
"members": members,
|
||||
}
|
||||
|
||||
return render(request, 'members/index.html', context)
|
||||
|
||||
|
||||
def jobs_view(request, slug=None):
|
||||
job_group = deque(JobGroup.objects.all())
|
||||
job_list = []
|
||||
|
||||
job_names = JobMember.jobs.get_job_names(slug=slug)
|
||||
active_members = JobMember.active_member.get_members_of_job(job_names=job_names)
|
||||
inactive_members = JobMember.inactive_member.get_members_of_job(job_names=job_names)
|
||||
|
||||
for idx, item in enumerate(job_names):
|
||||
job_list.append((job_names[idx], active_members[idx], inactive_members[idx]))
|
||||
|
||||
context = {
|
||||
"job_group": job_group,
|
||||
"job_list": job_list,
|
||||
}
|
||||
|
||||
return render(request, 'members/index.html', context)
|
||||
|
||||
|
||||
def members_view(request, filter=None):
|
||||
job_group = deque(JobGroup.objects.all())
|
||||
|
||||
if filter is None:
|
||||
members = deque(Member.all_members.all())
|
||||
elif filter in Member.MemberRole:
|
||||
members = deque(Member.all_members.filter(role=filter))
|
||||
else:
|
||||
members = None
|
||||
|
||||
context = {
|
||||
"job_group": job_group,
|
||||
"members": members,
|
||||
}
|
||||
|
||||
return render(request, 'members/index.html', context)
|
||||
|
||||
|
||||
def profile_view(request, member_name=None):
|
||||
job_group = deque(JobGroup.objects.all())
|
||||
member = None
|
||||
|
||||
member = deque(Member.all_members.filter(nickname=member_name))
|
||||
|
||||
context = {
|
||||
"job_group": job_group,
|
||||
"member": member,
|
||||
}
|
||||
|
||||
return render(request, 'members/index.html', context)
|
||||
|
||||
|
||||
class MemberViewSet(viewsets.ModelViewSet):
|
||||
"""
|
||||
API endpoint that allows users to be viewed or edited.
|
||||
|
||||
@@ -25,6 +25,20 @@ class MyPostAdmin(admin.ModelAdmin):
|
||||
list_filter = ['is_event']
|
||||
list_display = ['title', 'subtitle', 'slug', 'public_date']
|
||||
|
||||
def add_view(self, request, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
return super().add_view(
|
||||
request, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def change_view(self, request, object_id, form_url='', extra_context=None):
|
||||
extra_context = extra_context or {}
|
||||
extra_context['help_text'] = "Fette Schriften sind Pflichtfelder."
|
||||
return super().change_view(
|
||||
request, object_id, form_url, extra_context=extra_context,
|
||||
)
|
||||
|
||||
def save_model(self, request, obj, form, change):
|
||||
obj.author = request.user
|
||||
super().save_model(request, obj, form, change)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.validators import ValidationError
|
||||
from django.db import models
|
||||
from django.db.models import Q
|
||||
from django.urls import reverse
|
||||
@@ -61,7 +62,7 @@ class EventManager(models.Manager):
|
||||
return super().get_queryset().filter(
|
||||
Q(is_event=True)
|
||||
& Q(event_start__gt=date_today)
|
||||
).order_by('-public_date')
|
||||
).order_by('-event_start')
|
||||
|
||||
|
||||
class FetMeetingManager(models.Manager):
|
||||
@@ -168,7 +169,8 @@ class Post(models.Model):
|
||||
# TODO: Explain why this image is selected on save of the image
|
||||
# Query all posts that have a slug that equals one of the tags
|
||||
posts1 = Post.objects.filter(
|
||||
slug__in=self.tags.names()).filter(image__isnull=False)[0:1].all()
|
||||
slug__in=self.tags.names()
|
||||
).filter(image__isnull=False)[0:1].all()
|
||||
if len(posts1) > 0:
|
||||
return posts1.get().image
|
||||
|
||||
@@ -190,11 +192,12 @@ class Post(models.Model):
|
||||
"save the post with some defaults"
|
||||
if (self.id is None) and (not self.slug):
|
||||
self.slug = slugify(self.public_date.date()) + "-" + slugify(self.title)
|
||||
|
||||
super().save(*args, **kwargs)
|
||||
|
||||
self.tags.set(*re.findall(r'\#([\d\w-]+)', str(self.subtitle)),
|
||||
*re.findall(r'\#([\d\w-]+)', str(self.title)))
|
||||
self.tags.set(
|
||||
*re.findall(r'\#([\d\w-]+)', str(self.subtitle)),
|
||||
*re.findall(r'\#([\d\w-]+)', str(self.title))
|
||||
)
|
||||
|
||||
def __str__(self):
|
||||
return "Post (%s, %s): %s " % (self.slug, self.public_date.strftime("%d.%m.%Y"), self.title)
|
||||
@@ -239,12 +242,24 @@ class Event(Post):
|
||||
|
||||
class Meta:
|
||||
proxy = True
|
||||
|
||||
verbose_name = "Event"
|
||||
verbose_name_plural = "Events"
|
||||
|
||||
@property
|
||||
def event_start_month (self):
|
||||
def event_start_month(self):
|
||||
return self.event_start.strftime("%b")
|
||||
|
||||
@property
|
||||
def event_start_day(self):
|
||||
return self.event_start.strftime("%d")
|
||||
|
||||
def clean(self):
|
||||
if self.event_end is None or self.event_start is None:
|
||||
raise ValidationError(_('Das Datum des Events fehlt.'))
|
||||
elif self.event_end < self.event_start:
|
||||
raise ValidationError(_('Das Ende des Events liegt vor dem Beginn.'))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.is_event = True
|
||||
|
||||
@@ -263,6 +278,15 @@ class FetMeeting(Event):
|
||||
verbose_name = "Fet Sitzung"
|
||||
verbose_name_plural = "Fet Sitzungen"
|
||||
|
||||
def clean(self):
|
||||
if self.event_start is None:
|
||||
raise ValidationError(_('Das Datum des Events fehlt.'))
|
||||
|
||||
slug = slugify(self.event_start.date()) + "-" + slugify("Fachschaftssitzung")
|
||||
|
||||
if Post.objects.filter(slug=slug).count() != 0:
|
||||
raise ValidationError(_('Es existiert bereits eine Sitzung mit demselben Datum.'))
|
||||
|
||||
def save(self, *args, **kwargs):
|
||||
self.title = "Fachschaftssitzung"
|
||||
self.slug = slugify(self.event_start.date()) + "-" + slugify(self.title)
|
||||
|
||||
@@ -10,6 +10,7 @@ from rest_framework import viewsets
|
||||
# from rest_framework import permissions
|
||||
|
||||
from .models import Post, PostSerializer
|
||||
from members.models import Member
|
||||
# from documents import add_ep_to_response
|
||||
from documents import get_ep_sessionid2, get_pad_link,add_ep_cookie
|
||||
|
||||
@@ -41,14 +42,42 @@ def show(request, id=None):
|
||||
elif id != "" and id is not None:
|
||||
p = Post.objects.get(slug=(id))
|
||||
|
||||
post_author = Member.all_members.filter(nickname=p.author)
|
||||
|
||||
context = {
|
||||
"post": p,
|
||||
"next": get_next_dict().get(p.slug, None),
|
||||
"related_posts": p.tags.similar_objects(),
|
||||
"ep_link": get_pad_link(p.slug + "-agenda")
|
||||
"ep_link": get_pad_link(p.slug + "-agenda"),
|
||||
"author_image": post_author[0].image['avatar'].url
|
||||
}
|
||||
|
||||
response = render(request, 'posts/show.html', context)
|
||||
<<<<<<< HEAD
|
||||
return add_ep_cookie(request,response)
|
||||
=======
|
||||
response.set_cookie("HelloWorld", "TestWert", domain="https://etherpad2.2020.fet.at")
|
||||
ep_sessid, expires = get_ep_sessionid(request)
|
||||
response.set_cookie(
|
||||
"sessionID",
|
||||
ep_sessid,
|
||||
expires=expires,
|
||||
domain=".2020.fet.at",
|
||||
path="/"
|
||||
)
|
||||
'''
|
||||
response.set_cookie(
|
||||
"express_sid",
|
||||
ep_sessid,
|
||||
expires=expires,
|
||||
domain="https://andis.2020.fet.at",
|
||||
path="/etherpad"
|
||||
)
|
||||
'''
|
||||
# response=add_ep_to_response(request, response )
|
||||
|
||||
return response
|
||||
>>>>>>> 7fff88d1679058b52a4e2804534ea2dc76782873
|
||||
|
||||
###########
|
||||
# HELPERS #
|
||||
|
||||
6
fet2020/templates/admin/change_form.html
Normal file
6
fet2020/templates/admin/change_form.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{% extends "admin/change_form.html" %}
|
||||
{% load i18n admin_urls %}
|
||||
|
||||
{% block form_top %}
|
||||
{% if help_text %}<p>{{ help_text }}</p>{% endif %}
|
||||
{% endblock %}
|
||||
7
fet2020/templates/admin/submit_line.html
Normal file
7
fet2020/templates/admin/submit_line.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{% extends "admin/submit_line.html" %}
|
||||
{% load i18n admin_urls %}
|
||||
|
||||
{% block submit-row %}
|
||||
<a href="{% url opts|admin_urlname:'changelist' %}" class="closelink">{% trans 'Close' %}</a>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
@@ -13,7 +13,7 @@
|
||||
<div class="news-hero-text" >
|
||||
<hr>
|
||||
<div class="article-date">
|
||||
<p>Published on Jan 12, 2020 Just added now</p>
|
||||
<p>{{post.public_date}}</p>
|
||||
</div>
|
||||
<div class="article-title">
|
||||
<h1>{{post.title| safe}}</h1>
|
||||
@@ -55,8 +55,8 @@
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="medium-4 small-12 small-order-1 medium-order-2 padding-1">
|
||||
{% for post in events %}
|
||||
{% include 'posts/partials/_date_box.html' %}
|
||||
{% for post in events %}
|
||||
{% include 'posts/partials/_date_box.html' %}
|
||||
{% endfor %}
|
||||
|
||||
</div>
|
||||
|
||||
@@ -11,34 +11,38 @@
|
||||
<a id="members" data-toggle="tab" href="/members/A">Aktive Mitglieder</a>
|
||||
<a id="members" data-toggle="tab" href="/members/P">Inaktive Mitglieder</a>
|
||||
{% for job in job_group %}
|
||||
<a id="jobs-{{job.id}}" data-toggle="tab" href="/members/jobs/{{job.slug}}">{{job.name}}</a>
|
||||
<a id="jobs-{{job.slug}}" data-toggle="tab" href="/members/jobs/{{job.slug}}">{{job.name}}</a>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<!-- Tab panes -->
|
||||
<div class="tab-content" id="nav-tabContent">
|
||||
|
||||
{% for mem in member %}
|
||||
{% with member=mem %}
|
||||
{% include 'members/partials/_member_details.html' %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
<div id="members" class="tab-pane fade in active">
|
||||
{% if members == None %}
|
||||
{% else %}
|
||||
{% if members is not None %}
|
||||
{% include 'members/members_list.html' %}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div id="jobs-{{job.id}}" class="tab-pane">
|
||||
{% if members is None %}
|
||||
{% for job in job_list %}
|
||||
<div id="jobs-{{job.slug}}" class="tab-pane">
|
||||
<div class="grid-container">
|
||||
|
||||
{% for job in job_list %}
|
||||
{% if job_list|length > 1 %}
|
||||
<h2>{{job.0}}</h2>
|
||||
{% endif %}
|
||||
{% with active_members=job.1 inactive_members=job.2 %}
|
||||
{% include 'members/jobs_list.html' %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% if job_list|length > 1 %}
|
||||
<h2>{{job.0}}</h2>
|
||||
{% endif %}
|
||||
{% with active_members=job.1 inactive_members=job.2 %}
|
||||
{% include 'members/jobs_list.html' %}
|
||||
{% endwith %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
|
||||
<div class="grid-container">
|
||||
|
||||
Aktuelle Mitglieder: {{active_members.count}}
|
||||
<div class="grid-x">
|
||||
{% for mem in active_members %}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
<div class="grid-container">
|
||||
<h1> Mitarbeiter Liste </h1>
|
||||
<h2> Grid Style</h2>
|
||||
<div class="grid-x">
|
||||
{% for member in members %}
|
||||
@@ -16,11 +15,4 @@
|
||||
{% include 'members/partials/_member.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
<h2>Detail List</h2>
|
||||
<div class="grid-container">
|
||||
{% for member in members %}
|
||||
{% include 'members/partials/_member_details.html' %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
{# only thumb and name of member #}
|
||||
{% load thumbnail %}
|
||||
<a class="thumbnail member-thumb" style="width:150px;height:150px">
|
||||
{% if member.image %}<img src="{{member.image | thumbnail_url:'thumb'}}" />{% endif %}
|
||||
<a class="thumbnail member-thumb" href="/members/member/{{member.nickname}}" style="width:150px;height:150px">
|
||||
<img src="{{member.image.thumb.url}}" alt="" />
|
||||
<div class="thumb-layer"><div><h1>{{member.nickname}}</h1> <p>{{member.firstname}} {{member.surname}}</p></div></div>
|
||||
</a>
|
||||
@@ -1,4 +1,4 @@
|
||||
<a href ="">
|
||||
<a href ="posts/{{post.slug}}">
|
||||
<div class="date-box">
|
||||
<span>
|
||||
<span class="date-badge badge primary" style="">
|
||||
|
||||
@@ -16,9 +16,12 @@
|
||||
<div class="article-details">
|
||||
{{post.subtitle | tags_to_url }}
|
||||
{% if post.username != None %}
|
||||
<div class="article-author">
|
||||
<div class="arti
|
||||
<img src="{{post.username.image | thumbnail_url:'avatar'}}" alt="" />
|
||||
<a href="{% url 'member' post.username.nickname %}">{{post.username.nickname}}</a>
|
||||
<img src="{{author_image}}" alt="" />
|
||||
<a href="/members/member/{{post.author}}">{{post.author}}</a>
|
||||
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user