First Start of blog system

This commit is contained in:
Sam Collins 2017-02-16 00:04:44 +00:00 committed by Oliver Marks
parent c898514110
commit a5f0d97d54
19 changed files with 336 additions and 2 deletions

View File

@ -53,6 +53,7 @@ LOCAL_APPS = (
'mhackspace.feeds', 'mhackspace.feeds',
'mhackspace.contact', 'mhackspace.contact',
'mhackspace.members', 'mhackspace.members',
'mhackspace.blog',
) )
# See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps # See: https://docs.djangoproject.com/en/dev/ref/settings/#installed-apps

View File

@ -211,7 +211,7 @@ LOGGING = {
} }
# Custom Admin URL, use {% url 'admin:index' %} # Custom Admin URL, use {% url 'admin:index' %}
ADMIN_URL = env('DJANGO_ADMIN_URL', default='admin') ADMIN_URL = env('DJANGO_ADMIN_URL', default='admin/')
# Your production stuff: Below this line define 3rd party library settings # Your production stuff: Below this line define 3rd party library settings
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------

View File

@ -7,11 +7,13 @@ from django.conf.urls.static import static
from django.contrib import admin from django.contrib import admin
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.views import defaults as default_views from django.views import defaults as default_views
from django.contrib.auth import views as auth_views
from mhackspace.contact.views import contact from mhackspace.contact.views import contact
from mhackspace.members.views import MemberListView from mhackspace.members.views import MemberListView
from mhackspace.subscriptions import views as subscription from mhackspace.subscriptions import views as subscription
from mhackspace.base.feeds import LatestEntriesFeed from mhackspace.base.feeds import LatestEntriesFeed
from django.contrib.auth import views as auth_views from mhackspace.blog.feeds import BlogFeed, BlogCategoryFeed
urlpatterns = [ urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name='home'), url(r'^$', TemplateView.as_view(template_name='pages/home.html'), name='home'),
@ -20,6 +22,12 @@ urlpatterns = [
url(r'^mailing-list/$', TemplateView.as_view(template_name='pages/mailing-list.html'), name='group'), url(r'^mailing-list/$', TemplateView.as_view(template_name='pages/mailing-list.html'), name='group'),
url(r'^contact/$', contact, name='contact'), url(r'^contact/$', contact, name='contact'),
url(r'^blog/$', contact, name='contact'),
url(r'^blog/rss/$', BlogFeed()),
url(r'^blog/(?P<slug>[0-9A-Za-z_\-]+)/$', BlogCategoryFeed(), name='blog-item'),
url(r'^blog/category/(?P<slug>[0-9A-Za-z_\-]+)/$', BlogCategoryFeed(), name='blog-category'),
url(r'^blog/category/(?P<category>[0-9A-Za-z_\-]+)/rss/$', BlogCategoryFeed(), name='blog-category_feed'),
# need to be logged in for these urls # need to be logged in for these urls
url(r'^members/$', MemberListView.as_view(), name='members'), url(r'^members/$', MemberListView.as_view(), name='members'),

View File

@ -0,0 +1,23 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-15 21:46
from __future__ import unicode_literals
from django.db import migrations
import stdimage.models
import stdimage.utils
import stdimage.validators
class Migration(migrations.Migration):
dependencies = [
('base', '0002_auto_20170214_1911'),
]
operations = [
migrations.AlterField(
model_name='bannerimages',
name='scaled_image',
field=stdimage.models.StdImageField(blank=True, null=True, upload_to=stdimage.utils.UploadToAutoSlugClassNameDir('title'), validators=[stdimage.validators.MinSizeValidator(1200, 300)]),
),
]

View File

19
mhackspace/blog/admin.py Normal file
View File

@ -0,0 +1,19 @@
from django.contrib import admin
from django.contrib.admin import ModelAdmin
from mhackspace.blog.models import Post, Category
@admin.register(Post)
class PostAdmin(ModelAdmin):
date_hierarchy = 'published_date'
list_display = ('title', 'slug', 'author','active', 'members_only', 'published_date', 'updated_date')
list_filter = ('author', 'categories', 'members_only')
search_fields = ('title', 'author__name', 'author__id', 'published_date', 'updated_date')
readonly_fields = ('published_date',)
filter_horizontal = ('categories',)
prepopulated_fields = {"slug": ("title",)}
@admin.register(Category)
class CategoryAdmin(ModelAdmin):
list_display = ('name',)
prepopulated_fields = {"slug": ("name",)}

5
mhackspace/blog/apps.py Normal file
View File

@ -0,0 +1,5 @@
from django.apps import AppConfig
class BlogConfig(AppConfig):
name = 'blog'

47
mhackspace/blog/feeds.py Normal file
View File

@ -0,0 +1,47 @@
from django.contrib.syndication.views import Feed
from django.urls import reverse
from mhackspace.blog.models import Category, Post
class BlogFeed(Feed):
title = "Maidstone Hackspace Blog"
link = "/blog/"
description = "The latest blog posts and news from the Maidstone Hackspace site"
def items(self, category):
return Post.objects.select_related('author').filter(active=True, members_only=False)[:20]
def item_title(self, item):
return item.title
def item_description(self, item):
return item.description
def item_author_name(self, item):
return item.author.name
def item_author_email(self, item):
if item.author.public:
return item.author.email
def item_categories(self, item):
return item.categories.all()
def item_pubdate(self, item):
return item.published_date
def item_updateddate(self, item):
return item.updated_date
class BlogCategoryFeed(BlogFeed):
def get_object(self, request, category):
return Category.objects.filter(slug=category).first()
def items(self, category):
return Post.objects.select_related('author').filter(active=True, members_only=False, categories=category)[:20]
def title(self, category):
return "Maidstone Hackspace Blog: %s" % category.name
def description(self, category):
return category.description

View File

@ -0,0 +1,44 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-15 21:46
from __future__ import unicode_literals
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
import django.utils.timezone
import stdimage.models
import stdimage.utils
class Migration(migrations.Migration):
initial = True
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
]
operations = [
migrations.CreateModel(
name='Category',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('name', models.CharField(max_length=30)),
],
),
migrations.CreateModel(
name='Post',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('title', models.CharField(max_length=30)),
('image', stdimage.models.StdImageField(blank=True, null=True, upload_to=stdimage.utils.UploadToAutoSlugClassNameDir('title'))),
('description', models.TextField()),
('date', models.DateTimeField(default=django.utils.timezone.now)),
('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
('categories', models.ManyToManyField(to='blog.Category')),
],
options={
'ordering': ('date',),
},
),
]

View File

@ -0,0 +1,68 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-15 23:23
from __future__ import unicode_literals
from django.db import migrations, models
import django.utils.timezone
class Migration(migrations.Migration):
dependencies = [
('blog', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='post',
options={'ordering': ('updated_date',)},
),
migrations.RenameField(
model_name='post',
old_name='date',
new_name='published_date',
),
migrations.AddField(
model_name='category',
name='description',
field=models.TextField(default='Maidstone Hackspace Blog'),
preserve_default=False,
),
migrations.AddField(
model_name='category',
name='members_only',
field=models.BooleanField(default=False),
),
migrations.AddField(
model_name='category',
name='slug',
field=models.SlugField(default='url', max_length=100),
preserve_default=False,
),
migrations.AddField(
model_name='post',
name='active',
field=models.BooleanField(default=True),
),
migrations.AddField(
model_name='post',
name='slug',
field=models.SlugField(default='url', max_length=100, unique=True),
preserve_default=False,
),
migrations.AddField(
model_name='post',
name='updated_date',
field=models.DateTimeField(default=django.utils.timezone.now),
),
migrations.AlterField(
model_name='category',
name='name',
field=models.CharField(max_length=100),
),
migrations.AlterField(
model_name='post',
name='title',
field=models.CharField(max_length=100, unique=True),
),
]

View File

@ -0,0 +1,24 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-15 23:48
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('blog', '0002_auto_20170215_2323'),
]
operations = [
migrations.RemoveField(
model_name='category',
name='members_only',
),
migrations.AddField(
model_name='post',
name='members_only',
field=models.BooleanField(default=False),
),
]

View File

46
mhackspace/blog/models.py Normal file
View File

@ -0,0 +1,46 @@
from django.db import models
from django.utils import timezone
from django.urls import reverse
from mhackspace.users.models import User
from stdimage.models import StdImageField
from stdimage.utils import UploadToAutoSlugClassNameDir
class Category(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField(max_length=100)
description = models.TextField()
def __str__(self):
return self.name
class Post(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
categories = models.ManyToManyField(Category)
author = models.ForeignKey(User)
image = StdImageField(
upload_to=UploadToAutoSlugClassNameDir(populate_from='title'),
blank=True,
null=True,
variations={
'home': {
"width": 530,
"height": 220,
"crop": True}})
description = models.TextField()
published_date = models.DateTimeField(default=timezone.now)
updated_date = models.DateTimeField(default=timezone.now)
active = models.BooleanField(default=True)
members_only = models.BooleanField(default=False)
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse('blog-item', kwargs={'slug': self.slug})
class Meta:
ordering = ('updated_date',)

3
mhackspace/blog/tests.py Normal file
View File

@ -0,0 +1,3 @@
from django.test import TestCase
# Create your tests here.

3
mhackspace/blog/views.py Normal file
View File

@ -0,0 +1,3 @@
from django.shortcuts import render
# Create your views here.

View File

@ -0,0 +1,19 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-15 21:46
from __future__ import unicode_literals
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('feeds', '0001_initial'),
]
operations = [
migrations.AlterModelOptions(
name='article',
options={'ordering': ('pk',)},
),
]

View File

@ -53,3 +53,6 @@ class Article(models.Model):
def __str__(self): def __str__(self):
return self.title return self.title
class Meta:
ordering = ('pk',)

View File

@ -0,0 +1,20 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.10.5 on 2017-02-15 23:23
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('users', '0001_initial'),
]
operations = [
migrations.AddField(
model_name='user',
name='public',
field=models.BooleanField(default=False, help_text='If the users email is public on post feeds'),
),
]

View File

@ -11,6 +11,7 @@ from stdimage.models import StdImageField
class User(AbstractUser): class User(AbstractUser):
name = models.CharField(_('Name of User'), blank=True, max_length=255) name = models.CharField(_('Name of User'), blank=True, max_length=255)
public = models.BooleanField(default=False, help_text='If the users email is public on post feeds')
image = StdImageField( image = StdImageField(
upload_to='avatars/', upload_to='avatars/',
blank=True, blank=True,