Add Category support for teams and events, including card images. Fixes #37
This commit is contained in:
parent
7a577250b3
commit
9ff9b55692
17 changed files with 111 additions and 26 deletions
|
@ -1,8 +1,9 @@
|
|||
from django.contrib import admin
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
# Register your models here.
|
||||
from .models.locale import Language, Continent, Country, SPR, City
|
||||
from .models.profiles import UserProfile, Organization, Team, Member
|
||||
from .models.profiles import UserProfile, Organization, Team, Member, Category, Topic
|
||||
from .models.search import Searchable
|
||||
from .models.events import Place, Event, Attendee
|
||||
|
||||
|
@ -61,4 +62,13 @@ admin.site.register(Event, EventAdmin)
|
|||
admin.site.register(Member)
|
||||
admin.site.register(Attendee)
|
||||
|
||||
class CategoryAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'image')
|
||||
def image(self, obj):
|
||||
return (mark_safe('<img src="%s" title="%s" height="64px" />' % (obj.img_url, obj.name)))
|
||||
image.short_description = 'Image'
|
||||
admin.site.register(Category, CategoryAdmin)
|
||||
|
||||
class TopicAdmin(admin.ModelAdmin):
|
||||
list_display = ('name', 'category')
|
||||
list_filter = ('category',)
|
||||
|
|
|
@ -150,7 +150,7 @@ class DateTimeWidget(forms.SplitDateTimeWidget):
|
|||
class TeamForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Team
|
||||
fields = ['name', 'description', 'city', 'web_url', 'tz']
|
||||
fields = ['name', 'description', 'category', 'city', 'web_url', 'tz']
|
||||
widgets = {
|
||||
'city': Lookup(source='/api/cities/', label='name'),
|
||||
}
|
||||
|
@ -162,7 +162,7 @@ class TeamForm(forms.ModelForm):
|
|||
class NewTeamForm(forms.ModelForm):
|
||||
class Meta:
|
||||
model = Team
|
||||
fields = ['name', 'description', 'city', 'web_url', 'tz']
|
||||
fields = ['name', 'description', 'category', 'city', 'web_url', 'tz']
|
||||
widgets = {
|
||||
'city': Lookup(source='/api/cities/', label='name'),
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Generated by Django 2.0 on 2018-02-25 22:02
|
||||
# Generated by Django 2.0 on 2018-02-27 02:10
|
||||
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
@ -7,7 +7,7 @@ import django.db.models.deletion
|
|||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('events', '0008_add-team-description'),
|
||||
('events', '0010_userprofile_send_notifications'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
|
@ -17,7 +17,7 @@ class Migration(migrations.Migration):
|
|||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('name', models.CharField(max_length=256)),
|
||||
('description', models.TextField()),
|
||||
('img', models.URLField()),
|
||||
('img_url', models.URLField()),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
|
@ -34,16 +34,6 @@ class Migration(migrations.Migration):
|
|||
name='tags',
|
||||
field=models.CharField(blank=True, help_text='Comma-separates list of tags', max_length=128, null=True, verbose_name='Keyword Tags'),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='searchable',
|
||||
name='venue_name',
|
||||
field=models.CharField(blank=True, max_length=256),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='userprofile',
|
||||
name='avatar',
|
||||
field=models.URLField(blank=True, max_length=150, null=True, verbose_name='Photo Image'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='event',
|
||||
name='topics',
|
||||
|
@ -51,8 +41,8 @@ class Migration(migrations.Migration):
|
|||
),
|
||||
migrations.AddField(
|
||||
model_name='team',
|
||||
name='categories',
|
||||
field=models.ManyToManyField(blank=True, to='events.Category'),
|
||||
name='category',
|
||||
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to='events.Category'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='team',
|
28
events/migrations/0012_auto_20180227_0358.py
Normal file
28
events/migrations/0012_auto_20180227_0358.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
# Generated by Django 2.0 on 2018-02-27 03:58
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('events', '0011_auto_20180227_0210'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='event',
|
||||
name='topics',
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='searchable',
|
||||
name='img_url',
|
||||
field=models.URLField(default='https://gettogether.community/static/img/team_placeholder.png'),
|
||||
preserve_default=False,
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='event',
|
||||
name='tags',
|
||||
field=models.CharField(blank=True, max_length=128, null=True, verbose_name='Keyword Tags'),
|
||||
),
|
||||
]
|
|
@ -64,14 +64,12 @@ class Event(models.Model):
|
|||
created_by = models.ForeignKey(UserProfile, on_delete=models.CASCADE)
|
||||
created_time = models.DateTimeField(help_text=_('the date and time when the event was created'), default=datetime.datetime.now, db_index=True)
|
||||
|
||||
tags = models.CharField(verbose_name=_("Keyword Tags"), help_text=_('Comma-separates list of tags'), blank=True, null=True, max_length=128)
|
||||
tags = models.CharField(verbose_name=_("Keyword Tags"), blank=True, null=True, max_length=128)
|
||||
#image
|
||||
#replies
|
||||
|
||||
attendees = models.ManyToManyField(UserProfile, through='Attendee', related_name="attending", blank=True)
|
||||
|
||||
topics = models.ManyToManyField('Topic', blank=True)
|
||||
|
||||
def get_absolute_url(self):
|
||||
return reverse('show-event', kwargs={'event_id': self.id, 'event_slug': self.slug})
|
||||
|
||||
|
@ -102,6 +100,10 @@ def update_event_searchable(event):
|
|||
searchable.federation_node = origin_url
|
||||
searchable.federation_time = datetime.datetime.now()
|
||||
|
||||
if event.team.category:
|
||||
searchable.img_url = event.team.category.img_url
|
||||
else:
|
||||
searchable.img_url = "https://%s%s" % (site.domain, '/static/img/team_placeholder.png')
|
||||
searchable.event_title = event.name
|
||||
searchable.group_name = event.team.name
|
||||
searchable.start_time = event.start_time
|
||||
|
|
|
@ -157,7 +157,7 @@ class Team(models.Model):
|
|||
|
||||
members = models.ManyToManyField(UserProfile, through='Member', related_name="memberships", blank=True)
|
||||
|
||||
categories = models.ManyToManyField('Category', blank=True)
|
||||
category = models.ForeignKey('Category', on_delete=models.SET_NULL, blank=False, null=True)
|
||||
topics = models.ManyToManyField('Topic', blank=True)
|
||||
|
||||
@property
|
||||
|
@ -205,9 +205,17 @@ class Member(models.Model):
|
|||
class Category(models.Model):
|
||||
name = models.CharField(max_length=256)
|
||||
description = models.TextField()
|
||||
img = models.URLField(blank=False, null=False)
|
||||
img_url = models.URLField(blank=False, null=False)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Topic(models.Model):
|
||||
category = models.ForeignKey(Category, on_delete=models.CASCADE, null=False, blank=False)
|
||||
name = models.CharField(max_length=256)
|
||||
description = models.TextField()
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ import datetime
|
|||
class Searchable(models.Model):
|
||||
event_url = models.URLField(primary_key=True, null=False, blank=False)
|
||||
event_title = models.CharField(max_length=256, null=False, blank=False)
|
||||
img_url = models.URLField(null=False, blank=False)
|
||||
location_name = models.CharField(max_length=256, null=False, blank=False)
|
||||
group_name = models.CharField(max_length=256, null=False, blank=False)
|
||||
venue_name = models.CharField(max_length=256, null=False, blank=True)
|
||||
|
|
BIN
get_together/static/img/categories/activism.png
Normal file
BIN
get_together/static/img/categories/activism.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 118 KiB |
BIN
get_together/static/img/categories/dining.png
Normal file
BIN
get_together/static/img/categories/dining.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 114 KiB |
BIN
get_together/static/img/categories/music.png
Normal file
BIN
get_together/static/img/categories/music.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
BIN
get_together/static/img/categories/outdoor.png
Normal file
BIN
get_together/static/img/categories/outdoor.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 96 KiB |
BIN
get_together/static/img/categories/tech.png
Normal file
BIN
get_together/static/img/categories/tech.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
|
@ -14,7 +14,11 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
{% if event.team.category %}
|
||||
<img class="card-img-top" src="{{event.team.category.img_url}}" alt="{{event.name}}">
|
||||
{% else %}
|
||||
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{event.name}}">
|
||||
{% endif %}
|
||||
<p class="card-title">{{event.team.name}}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
{% if event.team.category %}
|
||||
<img class="card-img-top" src="{{event.team.category.img_url}}" alt="{{event.event_title}}">
|
||||
{% else %}
|
||||
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{event.event_title}}">
|
||||
{% endif %}
|
||||
<p class="card-title">{{event.group_name}}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
@ -57,7 +61,11 @@
|
|||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
{% if team.category %}
|
||||
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
|
||||
{% else %}
|
||||
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{team.name}}">
|
||||
{% endif %}
|
||||
<p class="card-title">{{team.name}}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
|
|
|
@ -30,6 +30,7 @@ $(document).ready(function(){
|
|||
});
|
||||
}
|
||||
})
|
||||
$("#id_category").selectmenu();
|
||||
$("#id_tz").selectmenu();
|
||||
});
|
||||
</script>
|
||||
|
|
|
@ -29,6 +29,7 @@ $(document).ready(function(){
|
|||
});
|
||||
}
|
||||
})
|
||||
$("#id_category").selectmenu();
|
||||
$("#id_tz").selectmenu();
|
||||
});
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
{% extends "get_together/base.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block styles %}
|
||||
<link href="{% static 'css/bootstrap-album.css' %}" rel="stylesheet"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% if my_teams %}
|
||||
|
@ -7,14 +12,41 @@
|
|||
<br/>
|
||||
{% endif %}
|
||||
|
||||
<h4>All Teams</h4>
|
||||
{% include "events/team_list.html" with teams_list=all_teams%}
|
||||
|
||||
{% if request.user.is_authenticated %}
|
||||
<br/>
|
||||
<form action="{% url 'create-team' %}" method="get">
|
||||
<button type="submit" class="btn btn-primary">Start a Team</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
<h4>All Teams</h4>
|
||||
<div class="fluid-container">
|
||||
<div class="row">
|
||||
{% for team in all_teams %}
|
||||
<div class="col-md-4">
|
||||
<div class="card mb-4 box-shadow">
|
||||
<div class="card-banner">
|
||||
{% if team.category %}
|
||||
<img class="card-img-top" src="{{team.category.img_url}}" alt="{{team.name}}">
|
||||
{% else %}
|
||||
<img class="card-img-top" src="{% static 'img/team_placeholder.png' %}" alt="{{team.name}}">
|
||||
{% endif %}
|
||||
<p class="card-title">{{team.name}}</p>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<p class="card-text"><strong><a class="card-link" href="{% url 'show-team' team.id %}">{{team.city}}</a></strong></p>
|
||||
<div class="d-flex justify-content-between align-items-center">
|
||||
<small class="text-muted">{{ team.members.count }} members</small>
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-primary" href="{% url 'show-team' team.id %}">View</a></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
|
Loading…
Reference in a new issue