Add Description field to Teams, allow Markdown for team and event descriptions, use Bootstrap layouts for team and event pages
This commit is contained in:
parent
bb88e55d49
commit
3a9d1b6863
8 changed files with 168 additions and 53 deletions
|
@ -149,7 +149,7 @@ class DateTimeWidget(SplitDateTimeWidget):
|
||||||
class TeamForm(ModelForm):
|
class TeamForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Team
|
model = Team
|
||||||
fields = ['name', 'country', 'spr', 'city', 'web_url', 'tz']
|
fields = ['name', 'description', 'country', 'spr', 'city', 'web_url', 'tz']
|
||||||
widgets = {
|
widgets = {
|
||||||
'country': Lookup(source='/api/country/', label='name'),
|
'country': Lookup(source='/api/country/', label='name'),
|
||||||
'spr': Lookup(source='/api/spr/', label='name'),
|
'spr': Lookup(source='/api/spr/', label='name'),
|
||||||
|
@ -160,13 +160,13 @@ class TeamForm(ModelForm):
|
||||||
class NewTeamForm(ModelForm):
|
class NewTeamForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
model = Team
|
model = Team
|
||||||
fields = ['name', 'city', 'web_url', 'tz']
|
fields = ['name', 'description', 'city', 'web_url', 'tz']
|
||||||
widgets = {
|
widgets = {
|
||||||
#'country': Lookup(source='/api/country/', label='name'),
|
#'country': Lookup(source='/api/country/', label='name'),
|
||||||
#'spr': Lookup(source='/api/spr/', label='name'),
|
#'spr': Lookup(source='/api/spr/', label='name'),
|
||||||
'city': Lookup(source='/api/cities/', label='name'),
|
'city': Lookup(source='/api/cities/', label='name'),
|
||||||
}
|
}
|
||||||
raw_id_fields = ('country','spr','city')
|
raw_id_fields = ('city')
|
||||||
|
|
||||||
class TeamEventForm(ModelForm):
|
class TeamEventForm(ModelForm):
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
18
events/migrations/0008_add-team-description.py
Normal file
18
events/migrations/0008_add-team-description.py
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# Generated by Django 2.0 on 2018-01-25 21:28
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('events', '0007_add-city-lonlat'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='team',
|
||||||
|
name='description',
|
||||||
|
field=models.TextField(blank=True, help_text='Team Description', null=True),
|
||||||
|
),
|
||||||
|
]
|
|
@ -26,7 +26,7 @@ class UserProfile(models.Model):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
try:
|
try:
|
||||||
if self.realname:
|
if self.realname:
|
||||||
return "%s (%s)" % (self.user.username, self.realname)
|
return self.realname
|
||||||
return "%s" % self.user.username
|
return "%s" % self.user.username
|
||||||
except:
|
except:
|
||||||
return "Unknown Profile"
|
return "Unknown Profile"
|
||||||
|
@ -121,6 +121,8 @@ class Team(models.Model):
|
||||||
name = models.CharField(_("Team Name"), max_length=256, null=False, blank=False)
|
name = models.CharField(_("Team Name"), max_length=256, null=False, blank=False)
|
||||||
organization = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.CASCADE)
|
organization = models.ForeignKey(Organization, null=True, blank=True, on_delete=models.CASCADE)
|
||||||
|
|
||||||
|
description = models.TextField(help_text=_('Team Description'), blank=True, null=True)
|
||||||
|
|
||||||
country = models.ForeignKey(Country, on_delete=models.CASCADE)
|
country = models.ForeignKey(Country, on_delete=models.CASCADE)
|
||||||
spr = models.ForeignKey(SPR, null=True, blank=True, on_delete=models.CASCADE)
|
spr = models.ForeignKey(SPR, null=True, blank=True, on_delete=models.CASCADE)
|
||||||
city = models.ForeignKey(City, null=True, blank=True, on_delete=models.CASCADE)
|
city = models.ForeignKey(City, null=True, blank=True, on_delete=models.CASCADE)
|
||||||
|
@ -178,7 +180,6 @@ class Member(models.Model):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def role_name(self):
|
def role_name(self):
|
||||||
print("Role name: %s=%s" % (self.role, Member.ROLES[self.role]))
|
|
||||||
return Member.ROLES[self.role][1]
|
return Member.ROLES[self.role][1]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|
|
@ -1,25 +1,54 @@
|
||||||
{% extends "get_together/base.html" %}
|
{% extends "get_together/base.html" %}
|
||||||
|
{% load markup %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>About {{ event.name }}</h2>
|
<div class="fluid-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<h2>{{ event.name }}
|
||||||
|
{% if can_edit_event %}
|
||||||
|
<a href="{% url 'edit-event' event.id %}" class="btn btn-secondary btn-sm">Edit Event</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if not is_attending %}
|
||||||
|
<a href="{% url 'attend-event' event.id %}" class="btn btn-success btn-sm">Attend</a>
|
||||||
|
{% endif %}
|
||||||
|
</h2><p class="text-muted">Hosted by <a href="{% url "show-team" team.id %}">{{ team.name }}</a></p><hr/>
|
||||||
|
|
||||||
<h4>Hosted by <a href="{% url "show-team" team.id %}">{{ team.name }}</a></h4>
|
<p>{{ event.summary|markdown }}</p>
|
||||||
{% include "events/event_details.html" %}
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<h4>Attendees ({{attendee_list.count}})</h4>
|
<table class="table">
|
||||||
{% include "events/attendee_list.html" with attendee_list=attendee_list %}
|
<tr>
|
||||||
<br/>
|
<td><b>Time:</b></td><td>{{ event.start_time }} - {{ event.end_time }}</td>
|
||||||
|
</tr><tr>
|
||||||
|
<td><b>Place:</b></td><td>{% if event.place %}{{ event.place }}{% else %}No place selected yet.{% endif %}</td>
|
||||||
|
</tr><tr>
|
||||||
|
{% if event.web_url %}
|
||||||
|
</tr><tr>
|
||||||
|
<td><b>Website:</b></td><td><a href="{{ event.web_url }}" target="_blank">{{ event.web_url }}</a></td>
|
||||||
|
{% endif %}
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if not is_attending %}
|
<div class="col-3-sm">
|
||||||
<form action="{% url 'attend-event' event.id %}" method="get">
|
<div class="container">
|
||||||
<button type="submit" class="btn btn-success">Attend</button>
|
<div class="row">
|
||||||
</form>
|
<div class="col"><h4>Attendees ({{attendee_list.count}})</h4><hr/></div>
|
||||||
{% endif %}
|
</div>
|
||||||
{% if can_edit_event %}
|
{% for attendee in attendee_list %}
|
||||||
<form action="{% url 'edit-event' event.id %}" method="get">
|
<div class="row">
|
||||||
<button type="submit" class="btn btn-secondary">Edit Event</button>
|
<div class="col"><p>
|
||||||
</form>
|
{{ attendee.user }}
|
||||||
{% endif %}
|
{% if attendee.role > 0 %}<small class="text-muted">{{ attendee.role_name }}</small>{% endif %}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-1">{{ attendee.status_name }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
|
@ -1,37 +1,58 @@
|
||||||
{% extends "get_together/base.html" %}
|
{% extends "get_together/base.html" %}
|
||||||
|
{% load markup %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h2>Welcome to {{ team.name }}</h2>
|
<div class="fluid-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md">
|
||||||
|
<h2>Welcome to {{ team.name }}
|
||||||
|
{% if can_edit_team %}
|
||||||
|
<a href="{% url 'edit-team' team.id %}" class="btn btn-secondary btn-sm">Edit Team</a>
|
||||||
|
{% endif %}
|
||||||
|
{% if is_member %}
|
||||||
|
{% if not team.owner_profile == request.user.profile %}<a href="{% url 'leave-team' team.id %}" class="btn btn-danger btn-sm">Leave Team</a>{% endif %}
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'join-team' team.id %}" class="btn btn-success btn-sm">Join Team</a>
|
||||||
|
{% endif %}
|
||||||
|
</h2><hr/>
|
||||||
|
|
||||||
<h4>Members</h4>
|
{% if team.description %}<p>{{ team.description|markdown }}</p><hr/>{% endif %}
|
||||||
{% include "events/member_list.html" %}
|
|
||||||
<br/>
|
|
||||||
|
|
||||||
<h4>Upcoming Events</h4>
|
<h4>Upcoming Events</h4>
|
||||||
{% include "events/event_list.html" %}
|
<div class="container">
|
||||||
<br/>
|
{% for event in events_list %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col"><a href="{{ event.get_absolute_url }}">{{event.name}}</a></div>
|
||||||
|
<div class="col">{{ event.place }}</div>
|
||||||
|
<div class="col">{{ event.start_time }}</div>
|
||||||
|
</div>
|
||||||
|
{% endfor %}
|
||||||
|
{% if can_create_event %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<br/><a href="{% url 'create-event' team.id %}" class="btn btn-primary">Plan a Get Together</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
{% if can_create_event %}
|
<div class="col-3-sm">
|
||||||
<br />
|
<div class="container">
|
||||||
<form action="{% url 'create-event' team.id %}" method="get">
|
<h4>Members</h4><hr/>
|
||||||
<button type="submit" class="btn btn-primary">Plan a Get Together</button>
|
{% for member in member_list %}
|
||||||
</form>
|
<div class="row">
|
||||||
{% endif %}
|
<div class="col"><p>
|
||||||
|
{{member.user}}
|
||||||
{% if can_edit_team %}
|
{% if member.role > 0 %}<small class="text-muted">{{ member.role_name }}</small>{% endif %}
|
||||||
<form action="{% url 'edit-team' team.id %}" method="get">
|
</p>
|
||||||
<button type="submit" class="btn btn-secondary">Edit Team</button>
|
</div>
|
||||||
</form>
|
</div>
|
||||||
{% endif %}
|
{% endfor %}
|
||||||
|
</div>
|
||||||
{% if is_member %}
|
</div>
|
||||||
<form action="{% url 'leave-team' team.id %}" method="get">
|
</div>
|
||||||
<button type="submit" class="btn btn-danger">Leave Team</button>
|
</div>
|
||||||
</form>
|
|
||||||
{% else %}
|
|
||||||
<form action="{% url 'join-team' team.id %}" method="get">
|
|
||||||
<button type="submit" class="btn btn-success">Join Team</button>
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
|
0
get_together/templatetags/__init__.py
Normal file
0
get_together/templatetags/__init__.py
Normal file
45
get_together/templatetags/markup.py
Normal file
45
get_together/templatetags/markup.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
"""
|
||||||
|
Copied from Django 1.4 alpha
|
||||||
|
|
||||||
|
Set of "markup" template filters for Django. These filters transform plain text
|
||||||
|
markup syntaxes to HTML; currently there is support for:
|
||||||
|
|
||||||
|
* Textile, which requires the PyTextile library available at
|
||||||
|
http://loopcore.com/python-textile/
|
||||||
|
|
||||||
|
* Markdown, which requires the Python-markdown library from
|
||||||
|
http://www.freewisdom.org/projects/python-markdown
|
||||||
|
|
||||||
|
* reStructuredText, which requires docutils from http://docutils.sf.net/
|
||||||
|
"""
|
||||||
|
|
||||||
|
from django import template
|
||||||
|
from django.template.defaultfilters import stringfilter
|
||||||
|
from django.conf import settings
|
||||||
|
from django.utils.safestring import mark_safe
|
||||||
|
|
||||||
|
import markdown as md
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.filter
|
||||||
|
@stringfilter
|
||||||
|
def markdown(value, arg=''):
|
||||||
|
"""
|
||||||
|
Runs Markdown over a given value, optionally using various
|
||||||
|
extensions python-markdown supports.
|
||||||
|
|
||||||
|
Syntax::
|
||||||
|
|
||||||
|
{{ value|markdown:"extension1_name,extension2_name..." }}
|
||||||
|
|
||||||
|
To enable safe mode, which strips raw HTML and only returns HTML
|
||||||
|
generated by actual Markdown syntax, pass "safe" as the first
|
||||||
|
extension in the list.
|
||||||
|
|
||||||
|
If the version of Markdown in use does not support extensions,
|
||||||
|
they will be silently ignored.
|
||||||
|
|
||||||
|
"""
|
||||||
|
return mark_safe(md.markdown(value))
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
certifi==2017.11.5
|
certifi==2017.11.5
|
||||||
chardet==3.0.4
|
chardet==3.0.4
|
||||||
defusedxml==0.5.0
|
defusedxml==0.5.0
|
||||||
|
dj-database-url==0.4.2
|
||||||
Django==2.0
|
Django==2.0
|
||||||
|
django-settings-export==1.2.1
|
||||||
djangorestframework==3.7.7
|
djangorestframework==3.7.7
|
||||||
idna==2.6
|
idna==2.6
|
||||||
|
Markdown==2.6.11
|
||||||
oauthlib==2.0.6
|
oauthlib==2.0.6
|
||||||
PyJWT==1.5.3
|
PyJWT==1.5.3
|
||||||
python3-openid==3.1.0
|
python3-openid==3.1.0
|
||||||
|
@ -15,5 +18,3 @@ six==1.11.0
|
||||||
social-auth-app-django==2.1.0
|
social-auth-app-django==2.1.0
|
||||||
social-auth-core==1.6.0
|
social-auth-core==1.6.0
|
||||||
urllib3==1.22
|
urllib3==1.22
|
||||||
dj-database-url==0.4.2
|
|
||||||
django-settings-export==1.2.1
|
|
||||||
|
|
Loading…
Reference in a new issue