Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions make_mozilla/projects/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ class TagAdmin(admin.ModelAdmin):
)


class GroupAdmin(admin.ModelAdmin):
prepopulated_fields = {'slug': ('name', ), }


class GroupMembershipAdmin(admin.ModelAdmin):
list_display = ('project', 'group', 'order', )
list_editable = ('order', )
list_filter = ('group', )


class TopicAdmin(TagAdmin):
pass

Expand All @@ -45,6 +55,8 @@ class ContributorAdmin(admin.ModelAdmin):


admin.site.register(models.Project, ProjectAdmin)
admin.site.register(models.Group, GroupAdmin)
admin.site.register(models.GroupMembership, GroupMembershipAdmin)
admin.site.register(models.Topic, TopicAdmin)
admin.site.register(models.Difficulty, DifficultyAdmin)
admin.site.register(models.Skill, SkillAdmin)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# -*- coding: utf-8 -*-
import datetime
from south.db import db
from south.v2 import SchemaMigration
from django.db import models


class Migration(SchemaMigration):

def forwards(self, orm):
# Adding model 'GroupMembership'
db.create_table('projects_groupmembership', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['projects.Project'])),
('group', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['projects.Group'])),
('order', self.gf('django.db.models.fields.IntegerField')(default=1, max_length=2)),
))
db.send_create_signal('projects', ['GroupMembership'])

# Adding model 'Group'
db.create_table('projects_group', (
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('name', self.gf('django.db.models.fields.CharField')(max_length=255)),
('slug', self.gf('django.db.models.fields.SlugField')(default='', unique=True, max_length=50)),
('body', self.gf('django.db.models.fields.TextField')(null=True, blank=True)),
('body_text_template', self.gf('django.db.models.fields.CharField')(max_length=255, null=True, blank=True)),
('take_body_from', self.gf('django.db.models.fields.CharField')(default='body', max_length=4)),
('image', self.gf('make_mozilla.core.fields.SizedImageField')(max_length=100)),
))
db.send_create_signal('projects', ['Group'])

def backwards(self, orm):
# Deleting model 'GroupMembership'
db.delete_table('projects_groupmembership')

# Deleting model 'Group'
db.delete_table('projects_group')

models = {
'events.campaign': {
'Meta': {'object_name': 'Campaign'},
'description': ('django.db.models.fields.TextField', [], {}),
'end': ('django.db.models.fields.DateField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'start': ('django.db.models.fields.DateField', [], {})
},
'events.partner': {
'Meta': {'ordering': "('name',)", 'object_name': 'Partner'},
'featured': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'for_campaign': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['events.Campaign']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'website': ('django.db.models.fields.URLField', [], {'max_length': '200'})
},
'projects.contributor': {
'Meta': {'object_name': 'Contributor'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'local_name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'partner': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['events.Partner']", 'null': 'True', 'blank': 'True'})
},
'projects.difficulty': {
'Meta': {'ordering': "['index', 'label', 'id']", 'object_name': 'Difficulty'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'index': ('django.db.models.fields.IntegerField', [], {'default': '1', 'max_length': '2'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'value': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
},
'projects.group': {
'Meta': {'object_name': 'Group'},
'body': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'body_text_template': ('django.db.models.fields.CharField', [], {'max_length': '255', 'null': 'True', 'blank': 'True'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('make_mozilla.core.fields.SizedImageField', [], {'max_length': '100'}),
'members': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['projects.Project']", 'through': "orm['projects.GroupMembership']", 'symmetrical': 'False'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'slug': ('django.db.models.fields.SlugField', [], {'default': "''", 'unique': 'True', 'max_length': '50'}),
'take_body_from': ('django.db.models.fields.CharField', [], {'default': "'body'", 'max_length': '4'})
},
'projects.groupmembership': {
'Meta': {'object_name': 'GroupMembership'},
'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Group']"}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'order': ('django.db.models.fields.IntegerField', [], {'default': '1', 'max_length': '2'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Project']"})
},
'projects.project': {
'Meta': {'ordering': "['-added']", 'object_name': 'Project'},
'added': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
'body': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'contributor': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['projects.Contributor']", 'null': 'True', 'blank': 'True'}),
'difficulties': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Difficulty']", 'null': 'True', 'blank': 'True'}),
'featured': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'image': ('make_mozilla.core.fields.SizedImageField', [], {'max_length': '100'}),
'link': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'skills': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Skill']", 'null': 'True', 'blank': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'default': "''", 'unique': 'True', 'max_length': '50'}),
'teaser': ('django.db.models.fields.TextField', [], {}),
'tools': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['tools.Tool']", 'null': 'True', 'blank': 'True'}),
'topics': ('django.db.models.fields.related.ManyToManyField', [], {'symmetrical': 'False', 'to': "orm['projects.Topic']", 'null': 'True', 'blank': 'True'}),
'url_hash': ('django.db.models.fields.CharField', [], {'max_length': '20', 'null': 'True', 'blank': 'True'})
},
'projects.projectstep': {
'Meta': {'object_name': 'ProjectStep'},
'content': ('django.db.models.fields.TextField', [], {}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'project': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'steps'", 'to': "orm['projects.Project']"})
},
'projects.skill': {
'Meta': {'ordering': "['index', 'label', 'id']", 'object_name': 'Skill'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'index': ('django.db.models.fields.IntegerField', [], {'default': '1', 'max_length': '2'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'value': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
},
'projects.topic': {
'Meta': {'ordering': "['index', 'label', 'id']", 'object_name': 'Topic'},
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'index': ('django.db.models.fields.IntegerField', [], {'default': '1', 'max_length': '2'}),
'label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'value': ('django.db.models.fields.SlugField', [], {'max_length': '50'})
},
'tools.tool': {
'Meta': {'ordering': "['name']", 'object_name': 'Tool'},
'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}),
'featured': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
'logo': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}),
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
'new': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
'slug': ('django.db.models.fields.SlugField', [], {'max_length': '50'}),
'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}),
'strapline': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'})
}
}

complete_apps = ['projects']
56 changes: 54 additions & 2 deletions make_mozilla/projects/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,14 @@ def get_absolute_url(self):
return self.link
return reverse('project', kwargs={'slug': self.slug})

@property
def groups(self):
try:
return self.group_set.all()
# because we have the 'dummy project' that doesn't have a primary key
except ValueError:
return None

@property
def content(self):
if self.steps.count():
Expand Down Expand Up @@ -91,6 +99,50 @@ def next(self):
return None


class Group(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(unique=True, default='',
help_text="Remember if you change this after a group has been saved it can cause broken links")
members = models.ManyToManyField(Project, through='GroupMembership')
body = models.TextField(null=True, blank=True,
help_text='Please paste your HTML in here - please remember to include any images behind an HTTPS server')
body_text_template = models.CharField(max_length=255, blank=True, null=True,
help_text="If supplying an HTML template for the body include the filename here. We look for templates in 'make_mozilla/projects/templates/groups/'")
take_body_from = models.CharField(max_length=4, choices=(
('body', 'body'),
('temp', 'body_text_template')
),
default='body',
help_text='Do you want the introduction text to be taken direct from the DB or from an HTML template file?')
image = fields.SizedImageField(
upload_to='projects',
help_text='Unless custom CSS is written this will appear in the top right of the page, next to the title',
storage=FileSystemStorage(**settings.UPLOADED_IMAGES),
sizes={
'poster': 515,
'flyer': (270, 165),
'featured': (200, 130),
'thumb': (126, 77),
})

def __unicode__(self):
return self.name

def get_absolute_url(self):
return reverse('group', kwargs={'slug': self.slug})

@property
def projects(self):
return self.members.all().order_by('groupmembership__order')


class GroupMembership(models.Model):
project = models.ForeignKey(Project)
group = models.ForeignKey(Group)
order = models.IntegerField(max_length=2, default=1,
help_text="Order can also be set on the listing page once saved")


class ProjectStep(models.Model):
project = models.ForeignKey('Project', related_name='steps')
content = models.TextField()
Expand Down Expand Up @@ -147,10 +199,10 @@ def name(self):
def website(self):
if self.partner:
return self.partner.website
return none
return None

@property
def logo(self):
if self.partner:
return self.partner.logo
return None
return None
8 changes: 8 additions & 0 deletions make_mozilla/projects/templates/projects/detail.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,14 @@ <h3>About this project</h3>
{% endif %}
{% endfor %}
</dl>
{% if project.groups %}
<h4>A project from:</h4>
<ul>
{% for g in project.groups %}
<li><a href="{{ g.get_absolute_url() }}">The {{ g.name }}</a></li>
{% endfor %}
</ul>
{% endif %}
</div>

{% if project.contributor %}
Expand Down
25 changes: 25 additions & 0 deletions make_mozilla/projects/templates/projects/group_index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "projects/base.html" %}

{% block page_title %}{{ group.name }} | {{ super() }}{% endblock %}

{% block page_id %}{{ group.slug }}{% endblock %}
{% block section_type %}project-group{% endblock %}

{% block content %}
<div class="group-intro">
<h1>welcome to the <em>{{ group.name }}</em></h1>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor typo: Welcome to the...

<img class="faux-bg" src="/media/partner_media/{{ group.image }}" alt="" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably better to use src="{{ group.image.thumb_url }}" (or similar) rather than rely on a path.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just wanted the original image (may have used the wrong kind of image field...)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure that group.image.url would work for that. Unless I'm not understanding what you're after.

{{ group.body|safe }}
</div>
<ol class="project-flyer-list">
{% for p in group.projects %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the brevity strictly required? for project in group.projects might be a bit more obvious.

<li><div class="project-flyer">
<a href="{{ p.get_absolute_url() }}">
<img src="{{ p.image.flyer_url }}">
<h4 class="title">{{ p }}</h4>
</a>
{% if p.contributor %}<p class="contributor">Contributed by {{ p.contributor }}</p>{% endif %}
</div></li>
{% endfor %}
</ol>
{% endblock %}
25 changes: 25 additions & 0 deletions make_mozilla/projects/templates/projects/groups/test_project.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "projects/base.html" %}

{% block page_title %}{{ group.name }} | {{ super() }}{% endblock %}

{% block page_id %}{{ group.slug }}{% endblock %}
{% block section_type %}project-group{% endblock %}

{% block content %}
<div class="group-intro">
<h1>welcome to the <em>{{ group.name }}</em></h1>
<img class="faux-bg" src="/media/partner_media/{{ group.image }}" alt="" />
<p>I like cake</p>
</div>
<ol class="project-flyer-list">
{% for p in group.projects %}
<li><div class="project-flyer">
<a href="{{ p.get_absolute_url() }}">
<img src="{{ p.image.flyer_url }}">
<h4 class="title">{{ p }}</h4>
</a>
{% if p.contributor %}<p class="contributor">Contributed by {{ p.contributor }}</p>{% endif %}
</div></li>
{% endfor %}
</ol>
{% endblock %}
7 changes: 7 additions & 0 deletions make_mozilla/projects/templates/projects/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,13 @@ <h3>Webmaker Projects:</h3>
<img src="{{ project.image.flyer_url }}">
<h4 class="title">{{ project }}</h4>
</a>
{% if project.groups %}
<ul class="project-group">
{% for g in project.groups %}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for group in project.groups might be better for future you :)

<li><a href="{{ g.get_absolute_url() }}">A <em>{{ g.name }}</em> project</a></li>
{% endfor %}
</ul>
{% endif %}
{% if project.contributor %}<p class="contributor">Contributed by {{ project.contributor }}</p>{% endif %}
</div></li>
{% endfor %}
Expand Down
2 changes: 2 additions & 0 deletions make_mozilla/projects/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
from make_mozilla.projects import views

urlpatterns = patterns('',
url(r'^groups/(?P<slug>[\w-]+)/$',
views.group, name='group'),
url(r'^$',
views.index, name='projects'),
url(r'(?P<slug>[\w-]+)/$',
Expand Down
17 changes: 15 additions & 2 deletions make_mozilla/projects/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def __call__(self, request):


def submit(request):
return jingo.render(request, 'projects/submit.html');
return jingo.render(request, 'projects/submit.html')


def details(request, slug):
Expand All @@ -126,4 +126,17 @@ def details(request, slug):

return jingo.render(request, 'projects/detail.html', {
'project': project
});
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I hate it when I do that.



def group(request, slug):
group = get_object_or_404(models.Group, slug=slug)

if group.take_body_from == 'temp':
template = 'projects/groups/%s' % group.body_text_template
else:
template = 'projects/group_index.html'

return jingo.render(request, template, {
'group': group
})
Loading