Commit c4bbf2af authored by okhin's avatar okhin 🚴

Merge branch '18-improve-the-usability-of-admin-interface-and-models' into 'master'

Resolve "Improve the usability of admin interface and models"

Closes #18

See merge request !7
parents c721b074 bc71115f
Pipeline #1162 passed with stage
in 53 seconds
from django.contrib import admin
from modeltranslation.admin import TranslationAdmin, TranslationTabularInline
from modeltranslation.admin import TranslationAdmin, TranslationStackedInline
from picampaign.campaign.models import Campaign, CampaignContact, Argumentary
from picampaign.organization.models import Organization
......@@ -13,11 +13,15 @@ class InlineContact(admin.TabularInline):
class InlineImporter(admin.TabularInline):
model = Importer
class InlineTranslationArgumentary(TranslationTabularInline):
class InlineTranslationArgumentary(TranslationStackedInline):
model = Argumentary
class CampaignAdmin(TranslationAdmin):
inlines = [InlineTranslationArgumentary, InlineContact, InlineImporter]
list_display = ('title', 'organization', 'start_date', 'end_date', 'phone_filter',)
list_filter = ('organization', 'start_date', 'end_date',)
list_select_related = ('organization',)
search_fields = ['title', 'organization__name']
def get_queryset(self, request):
qs = super(CampaignAdmin, self).get_queryset(request)
......@@ -35,6 +39,11 @@ class CampaignAdmin(TranslationAdmin):
request,
**kwargs)
class CampaignContactAdmin(admin.ModelAdmin):
list_display = ('contact', 'campaign', 'weight')
list_select_related = ('contact', 'campaign',)
list_filter = ('campaign',)
search_fields = ['campaign__title', 'contact__first_name', 'contact__last_name']
def get_queryset(self, request):
qs = super(CampaignContactAdmin, self).get_queryset(request)
if request.user.is_superuser:
......@@ -44,6 +53,10 @@ class CampaignContactAdmin(admin.ModelAdmin):
class ArgumentaryAdmin(TranslationAdmin):
list_display = ('title', 'campaign',)
list_select_related = ('campaign',)
list_filter = ('campaign',)
def get_queryset(self, request):
qs = super(ArgumentaryAdmin, self).get_queryset(request)
if request.user.is_superuser:
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.2 on 2017-06-14 10:04
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('campaign', '0010_auto_20170613_2015'),
]
operations = [
migrations.AlterModelOptions(
name='argumentary',
options={'verbose_name': 'Argument', 'verbose_name_plural': 'Arguments'},
),
]
......@@ -27,6 +27,10 @@ class Argumentary(models.Model):
title = models.CharField(max_length=255, verbose_name=_('title'), null=True, blank=True)
text = RichTextField(null=True)
class Meta:
verbose_name = _("Argument")
verbose_name_plural = _("Arguments")
def __str__(self):
args = {'title': self.campaign.title}
return _('Argumentary for %(title)s') % args
......
from django.contrib import admin
from django.contrib.contenttypes.models import ContentType
from django.http import HttpResponseRedirect
from picampaign.organization.models import FeedbackCategory
from picampaign.feedback.models import Feedback
......@@ -9,10 +11,15 @@ class FeedbackFilterByCategory(admin.SimpleListFilter):
def lookups(self, request, model_admin):
if request.user.is_superuser:
feedbacks = Feedback.objects.all().values_list('category__id', 'category__name')
feedbacks = Feedback.objects.all().values_list(
'category__id',
'category__name')
else:
user_orgs = [x.id for x in request.user.organizations.all()]
feedbacks = Feedback.objects.filter(category__organisation__in=user_orgs).values_list('category_id', 'category_name')
feedbacks = Feedback.objects.filter(
category__organisation__in=user_orgs).values_list(
'category_id',
'category_name')
return ((f[0], f[1],) for f in sorted(set(feedbacks), key=lambda f: f[1]))
......@@ -21,8 +28,65 @@ class FeedbackFilterByCategory(admin.SimpleListFilter):
return queryset.filter(category__id=self.value())
return queryset
class FeedbackFilterByOrganization(admin.SimpleListFilter):
title = 'organization'
parameter_name = 'organization'
def lookups(self, request, model_admin):
if request.user.is_superuser:
feedbacks = Feedback.objects.all().values_list(
'category__organization__id',
'category__organization__name')
else:
user_orgs = [x.id for x in request.user.organizations.all()]
feedbacks = Feedback.objects.filter(
category__organization__in=user_orgs).values_list(
'category__organization__id',
'category__organization__name')
return ((f[0], f[1],) for f in sorted(set(feedbacks), key=lambda f: f[1]))
def queryset(self, request, queryset):
if self.value():
return queryset.filter(category__organization__id=self.value())
return queryset
class FeedbackFilterByCampaign(admin.SimpleListFilter):
title = 'campaign'
parameter_name = 'campaign'
def lookups(self, request, model_admin):
if request.user.is_superuser:
feedbacks = Feedback.objects.all().values_list(
'callee__campaign__id',
'callee__campaign__title')
else:
user_orgs = [x.id for x in request.user.organizations.all()]
feedbacks = Feedback.objects.filter(
category__organization__in=user_orgs).values_list(
'callee__campaign__id',
'callee__campaign__title')
return ((f[0], f[1],) for f in sorted(set(feedbacks), key=lambda f: f[1]))
def queryset(self, request, queryset):
if self.value():
return queryset.filter(callee__campaign__id=self.value())
return queryset
class FeedbackAdmin(admin.ModelAdmin):
list_filter = (FeedbackFilterByCategory,)
date_hierarchy = 'date'
list_display = ('callee', 'category',
'date', 'organization',)
list_filter = (FeedbackFilterByCategory,
FeedbackFilterByOrganization,
FeedbackFilterByCampaign)
search_fields = ['category__organization__name', 'category__name',
'callee__contact__first_name',
'callee__contact__last_name',
'callee__campaign__title']
actions = ['export_csv']
def get_queryset(self, request):
qs = super(FeedbackAdmin, self).get_queryset(request)
......@@ -31,4 +95,11 @@ class FeedbackAdmin(admin.ModelAdmin):
user_orgs = [x.id for x in request.user.organizations.all()]
return qs.filter(category__organization__in=user_orgs)
def export_csv(self, request, queryset):
selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
ct = ContentType.objects.get_for_model(queryset.model)
return HttpResponseRedirect("/export/?ct={}&ids={}".format(ct.pk, ",".join(selected)))
export_csv.short_description = "Export feedbacks as CSV"
admin.site.register(Feedback, FeedbackAdmin)
......@@ -11,6 +11,9 @@ class Feedback(models.Model):
comment = models.CharField(max_length=512, blank=True)
date = models.DateTimeField(auto_now_add=True)
def organization(self):
return self.category.organization
def __str__(self):
return _('feedback for %(callee contact)s on %(campaign title)s') % \
{'callee contact': self.callee.contact,
......
import json
import csv
from django.http import HttpResponse
from django.views.decorators.csrf import csrf_exempt
from django.contrib.contenttypes.models import ContentType
from rest_framework import viewsets
from rest_framework.response import Response
......@@ -23,3 +26,25 @@ class FeedbackViewSet(viewsets.ViewSet):
return Response(feedback.id)
except Exception as e:
raise e
def FeedbackExportCSVView(request):
response = HttpResponse(content_type='text/csv')
response['Content-Disposition'] = 'attachment; filename="feedbacks.csv"'
model = ContentType.objects.get_for_id(int(request.GET['ct']))
feedbacks = model.model_class().objects.filter(
pk__in=[int(pk) for pk in request.GET['ids'].split(',')]).select_related(
'callee', 'callee__contact', 'callee__campaign', 'category')
writer = csv.writer(response)
# A Header is nice
writer.writerow(['Date', 'Contact', 'Campaign', 'Category', 'Comment'])
for feedback in feedbacks:
writer.writerow([feedback.date,
feedback.callee.contact.full_name,
feedback.callee.campaign,
feedback.category,
feedback.comment])
return response
......@@ -17,6 +17,8 @@ class GroupInline(admin.TabularInline):
class GroupTypeAdmin(admin.ModelAdmin):
list_display = ('name', 'organization',)
list_filter = ('organization',)
inlines = [GroupInline]
def get_queryset(self, request):
......@@ -37,6 +39,10 @@ class GroupTypeAdmin(admin.ModelAdmin):
class GroupAdmin(admin.ModelAdmin):
list_display = ('name', 'type', 'organization',)
list_filter = ('type',)
search_fields = ['name',]
def get_queryset(self, request):
qs = super(GroupAdmin, self).get_queryset(request)
if request.user.is_superuser:
......
......@@ -38,6 +38,9 @@ class Group(models.Model):
contacts = models.ManyToManyField(Contact, blank=True,
related_name='groups')
def organization(self):
return self.type.organization
def __str__(self):
return self.name
......
......@@ -6,7 +6,7 @@ from rest_framework_nested import routers
from picampaign.campaign.views import (CampaignViewSet, CampaignContactViewSet,
ArgumentaryViewSet)
from picampaign.feedback.views import FeedbackViewSet
from picampaign.feedback.views import FeedbackViewSet, FeedbackExportCSVView
from picampaign.organization.views import (CategoryViewSet, GroupTypeViewSet,
GroupViewSet, OrganizationViewSet)
......@@ -29,5 +29,6 @@ urlpatterns = [
url(r'^', include(router.urls)),
url(r'^', include(campaign_router.urls)),
url(r'^i18n/', include('django.conf.urls.i18n')),
url(r'^docs/', include('rest_framework_docs.urls'))
url(r'^docs/', include('rest_framework_docs.urls')),
url(r'^export/', FeedbackExportCSVView),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment