Newer
Older
from django.db import models
from django.core.exceptions import ValidationError
from django.utils.functional import cached_property
from django.core.paginator import EmptyPage, PageNotAnInteger, Paginator
from django.conf import settings
from modelcluster.fields import ParentalKey
from wagtail.wagtailcore.models import Orderable
from wagtail.wagtailcore.fields import StreamField
from wagtail.wagtailadmin.edit_handlers import (
FieldPanel,
InlinePanel,
MultiFieldPanel,
StreamFieldPanel
)
from wagtail.wagtailimages.edit_handlers import ImageChooserPanel
from opentech.public.utils.blocks import StoryBlock
from opentech.public.utils.models import BasePage, BaseFunding, FundingMixin
class SocialMediaProfile(models.Model):
person_page = ParentalKey(
'PersonPage',
related_name='social_media_profile'
)
site_titles = (
('twitter', "Twitter"),
('linkedin', "LinkedIn"),
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
)
site_urls = (
('twitter', 'https://twitter.com/'),
('linkedin', 'https://www.linkedin.com/in/')
)
service = models.CharField(
max_length=200,
choices=site_titles
)
username = models.CharField(max_length=255)
@property
def profile_url(self):
return dict(self.site_urls)[self.service] + self.username
def clean(self):
if self.service == 'twitter' and self.username.startswith('@'):
self.username = self.username[1:]
class PersonType(models.Model):
title = models.CharField(max_length=255)
def __str__(self):
return self.title
class PersonPagePersonType(models.Model):
page = ParentalKey('PersonPage', related_name='person_types')
person_type = models.ForeignKey(
'PersonType',
related_name='+'
)
panels = [
FieldPanel('person_type')
]
def __str__(self):
return self.person_type.title
page = ParentalKey('PersonPage', related_name='funding')
class PersonContactInfomation(Orderable):
methods = (
('irc', 'IRC'),
('im_jabber_xmpp', 'IM/Jabber/XMPP'),
('phone', 'Phone'),
('pgp', 'PGP fingerprint'),
('otr', 'OTR fingerprint'),
)
page = ParentalKey('PersonPage', related_name='contact_details')
contact_method = models.CharField(max_length=255, choices=methods, blank=True)
other_method = models.CharField(max_length=255, blank=True, verbose_name='Other')
contact_detail = models.CharField(max_length=255)
panels = [
FieldRowPanel([
FieldPanel('contact_method'),
FieldPanel('other_method'),
]),
FieldPanel('contact_detail'),
@property
def method_display(self):
return self.other_method or self.get_contact_method_display()
def clean(self):
if not (self.contact_method or self.other_method):
raise ValidationError({
'contact_method': 'Please select or type at least one contact method.',
'other_method': '',
})
if self.contact_method and self.other_method:
raise ValidationError({
'contact_method': 'Please only select or type one contact method.',
'other_method': '',
})
class PersonPage(FundingMixin, BasePage):
subpage_types = []
parent_page_types = ['PersonIndexPage']
first_name = models.CharField(max_length=255)
last_name = models.CharField(max_length=255)
photo = models.ForeignKey(
'images.CustomImage',
null=True,
blank=True,
related_name='+',
on_delete=models.SET_NULL
)
job_title = models.CharField(max_length=255)
introduction = models.TextField(blank=True)
website = models.URLField(blank=True, max_length=255)
biography = StreamField(StoryBlock(), blank=True)
email = models.EmailField(blank=True)
content_panels = BasePage.content_panels + [
MultiFieldPanel([
FieldPanel('first_name'),
FieldPanel('last_name'),
], heading="Name"),
ImageChooserPanel('photo'),
FieldPanel('job_title'),
InlinePanel('social_media_profile', label='Social accounts'),
FieldPanel('website'),
MultiFieldPanel([
FieldPanel('email'),
InlinePanel('contact_details', label='Other Contact Methods'),
], heading='Contact information'),
InlinePanel('person_types', label='Person types'),
FieldPanel('introduction'),
] + FundingMixin.content_panels
class PersonIndexPage(BasePage):
subpage_types = ['PersonPage']
parent_page_types = ['home.HomePage']
@cached_property
def people(self):
return self.get_children().specific().live().public()
def get_context(self, request, *args, **kwargs):
page_number = request.GET.get('page')
paginator = Paginator(self.people, settings.DEFAULT_PER_PAGE)
try:
people = paginator.page(page_number)
except PageNotAnInteger:
people = paginator.page(1)
except EmptyPage:
people = paginator.page(paginator.num_pages)
context = super().get_context(request, *args, **kwargs)
context.update(people=people)
return context