Added Blog and Feeds API

This commit is contained in:
Sam Collins 2017-02-25 15:39:57 +00:00 committed by Oliver Marks
parent 6c463d3b86
commit 9db20fb458
8 changed files with 117 additions and 18 deletions

View File

@ -28,12 +28,7 @@ DJANGO_APPS = (
'django.contrib.sites', 'django.contrib.sites',
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'stdimage', 'django.contrib.humanize',
# Useful template tags:
# 'django.contrib.humanize',
# Admin
'django.contrib.admin', 'django.contrib.admin',
) )
THIRD_PARTY_APPS = ( THIRD_PARTY_APPS = (
@ -41,6 +36,8 @@ THIRD_PARTY_APPS = (
'allauth', # registration 'allauth', # registration
'allauth.account', # registration 'allauth.account', # registration
'allauth.socialaccount', # registration 'allauth.socialaccount', # registration
'stdimage',
'rest_framework',
) )
# Apps specific for this project go here. # Apps specific for this project go here.
@ -270,7 +267,7 @@ PAYMENT_PROVIDERS = {
'credentials': { 'credentials': {
'merchant_id': env('BRAINTREE_MERCHANT_ID'), 'merchant_id': env('BRAINTREE_MERCHANT_ID'),
'public_key': env('BRAINTREE_PUBLIC_KEY'), 'public_key': env('BRAINTREE_PUBLIC_KEY'),
'private_key': env('BRAINTREE_PRIVATE_KEY') , 'private_key': env('BRAINTREE_PRIVATE_KEY'),
} }
}, },
'paypal': { 'paypal': {
@ -280,21 +277,20 @@ PAYMENT_PROVIDERS = {
"client_id": env('PAYPAL_CLIENT_ID'), "client_id": env('PAYPAL_CLIENT_ID'),
"client_secret": env('PAYPAL_CLIENT_SECRET')} "client_secret": env('PAYPAL_CLIENT_SECRET')}
}, },
'gocardless':{ 'gocardless': {
'environment': 'sandbox', 'environment': 'sandbox',
'credentials': { 'credentials': {
'app_id': env('GOCARDLESS_APP_ID') , 'app_id': env('GOCARDLESS_APP_ID'),
'app_secret': env('GOCARDLESS_APP_SECRET'), 'app_secret': env('GOCARDLESS_APP_SECRET'),
'access_token': env('GOCARDLESS_ACCESS_TOKEN'), 'access_token': env('GOCARDLESS_ACCESS_TOKEN'),
'merchant_id': env('GOCARDLESS_MERCHANT_ID'), 'merchant_id': env('GOCARDLESS_MERCHANT_ID'),
}, },
'redirect_url':'https://test.maidstone-hackspace.org.uk' 'redirect_url': 'https://test.maidstone-hackspace.org.uk'
} }
} }
SASS_PRECISION = 8 SASS_PRECISION = 8
SASS_PROCESSOR_INCLUDE_DIRS = [ SASS_PROCESSOR_INCLUDE_DIRS = [
# str(ROOT_DIR), # str(ROOT_DIR),
str(APPS_DIR) + '/static/sass', str(APPS_DIR) + '/static/sass',
@ -306,3 +302,13 @@ SASS_PROCESSOR_ENABLED = True
SASS_PROCESSOR_AUTO_INCLUDE = True SASS_PROCESSOR_AUTO_INCLUDE = True
EMAIL_SUPPORT = 'support@maidstone-hackspace.org.uk' EMAIL_SUPPORT = 'support@maidstone-hackspace.org.uk'
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': (
'rest_framework.filters.SearchFilter',
'django_filters.rest_framework.DjangoFilterBackend',
'rest_framework.filters.OrderingFilter'
),
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 50
}

View File

@ -8,21 +8,30 @@ 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 django.contrib.auth import views as auth_views
from rest_framework.routers import DefaultRouter
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 mhackspace.blog.feeds import BlogFeed, BlogCategoryFeed from mhackspace.blog.feeds import BlogFeed, BlogCategoryFeed
from mhackspace.blog.views import blog from mhackspace.blog.views import blog, PostViewSet, CategoryViewSet
from mhackspace.feeds.views import FeedViewSet, ArticleViewSet
router = DefaultRouter()
router.register(r'posts', PostViewSet)
router.register(r'categories', CategoryViewSet)
router.register(r'feeds', FeedViewSet)
router.register(r'articles', ArticleViewSet)
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'),
url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name='about'), url(r'^about/$', TemplateView.as_view(template_name='pages/about.html'), name='about'),
url(r'^chat/$', TemplateView.as_view(template_name='pages/chat.html'), name='chat'), url(r'^chat/$', TemplateView.as_view(template_name='pages/chat.html'), name='chat'),
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'^api/v1/', include(router.urls, namespace='v1')),
url(r'^blog/$', blog, name='contact'), url(r'^blog/$', blog, name='contact'),
url(r'^blog/rss/$', BlogFeed()), url(r'^blog/rss/$', BlogFeed()),
url(r'^blog/(?P<slug>[0-9A-Za-z_\-]+)/$', blog, name='blog-item'), url(r'^blog/(?P<slug>[0-9A-Za-z_\-]+)/$', blog, name='blog-item'),

View File

@ -6,6 +6,7 @@ from mhackspace.users.models import User
from stdimage.models import StdImageField from stdimage.models import StdImageField
from stdimage.utils import UploadToAutoSlugClassNameDir from stdimage.utils import UploadToAutoSlugClassNameDir
class Category(models.Model): class Category(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)
slug = models.SlugField(max_length=100) slug = models.SlugField(max_length=100)
@ -17,6 +18,7 @@ class Category(models.Model):
def get_absolute_url(self): def get_absolute_url(self):
return reverse('blog-category', kwargs={'category': self.slug}) return reverse('blog-category', kwargs={'category': self.slug})
class Post(models.Model): class Post(models.Model):
title = models.CharField(max_length=100, unique=True) title = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True) slug = models.SlugField(max_length=100, unique=True)

View File

@ -0,0 +1,15 @@
from rest_framework import serializers
from mhackspace.blog.models import Post, Category
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ('id', 'title', 'slug', 'categories', 'author', 'image', 'description', 'published_date', 'updated_date')
class CategorySerializer(serializers.ModelSerializer):
class Meta:
model = Category
fields = ('id', 'name', 'slug', 'description')

View File

@ -1,18 +1,24 @@
from django.shortcuts import render from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from rest_framework import filters, viewsets
from django_filters import DateTimeFromToRangeFilter
from django_filters.rest_framework import FilterSet
from django_filters.widgets import RangeWidget
from mhackspace.blog.models import Post, Category from mhackspace.blog.models import Post, Category
from mhackspace.blog.serializers import PostSerializer, CategorySerializer
def blog(request, slug=None, category=None): def blog(request, slug=None, category=None):
categories = Category.objects.all() categories = Category.objects.all()
try: try:
if slug is not None: if slug is not None:
blog_posts = Post.objects.filter(slug=slug) blog_posts = Post.objects.filter(active=True, slug=slug)
elif category is not None: elif category is not None:
category = Category.objects.filter(slug=category) category = Category.objects.filter(slug=category)
blog_posts = Post.objects.filter(categories=category) blog_posts = Post.objects.filter(active=True, categories=category)
else: else:
blog_posts = Post.objects.all() blog_posts = Post.objects.filter(active=True)
except Category.DoesNotExist: except Category.DoesNotExist:
raise Http404("Category does not exist") raise Http404("Category does not exist")
except Post.DoesNotExist: except Post.DoesNotExist:
@ -29,3 +35,28 @@ def blog(request, slug=None, category=None):
posts = paginator.page(paginator.num_pages) posts = paginator.page(paginator.num_pages)
return render(request, 'blog/posts.html', {'posts': posts, 'categories': categories}) return render(request, 'blog/posts.html', {'posts': posts, 'categories': categories})
class PostFilter(FilterSet):
published_date = DateTimeFromToRangeFilter(widget=RangeWidget(attrs={'placeholder': 'dd/mm/yyyy hh:mm'}))
updated_date = DateTimeFromToRangeFilter(widget=RangeWidget(attrs={'placeholder': 'dd/mm/yyyy hh:mm'}))
class Meta:
model = Post
fields = ('title', 'slug', 'author__name', 'published_date', 'updated_date')
class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.filter(active=True)
filter_class = PostFilter
serializer_class = PostSerializer
search_fields = ('title', 'slug', 'categories', 'author__name')
ordering_fields = ('title', 'published_date', 'updated_date', 'author')
class CategoryViewSet(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
search_fields = ('name', 'slug')
ordering_fields = ('name', 'slug')
filter_fields = ('name', 'slug')

View File

@ -0,0 +1,15 @@
from rest_framework import serializers
from mhackspace.feeds.models import Feed, Article
class FeedSerializer(serializers.ModelSerializer):
class Meta:
model = Feed
fields = ('home_url', 'feed_url', 'title', 'author', 'tags', 'image')
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ('url', 'feed', 'original_image', 'image', 'description', 'date')

19
mhackspace/feeds/views.py Normal file
View File

@ -0,0 +1,19 @@
from rest_framework import filters, viewsets
from mhackspace.feeds.models import Feed, Article
from mhackspace.feeds.serializers import FeedSerializer, ArticleSerializer
class FeedViewSet(viewsets.ModelViewSet):
queryset = Feed.objects.filter(enabled=True)
serializer_class = FeedSerializer
search_fields = ('home_url', 'feed_url', 'title', 'author__name', 'tags', 'image')
ordering_fields = ('home_url', 'feed_url', 'title', 'author', 'tags', 'image')
filter_fields = ('home_url', 'feed_url', 'title', 'author', 'tags', 'image')
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.filter(displayed=True)
serializer_class = ArticleSerializer
search_fields = ('url', 'feed__title', 'original_image', 'description', 'date')
ordering_fields = ('url', 'feed', 'date')
filter_fields = ('url', 'feed', 'date')

View File

@ -58,3 +58,5 @@ braintree==3.35.0
django-autofixture==0.12.1 django-autofixture==0.12.1
git+https://github.com/olymk2/scaffold.git git+https://github.com/olymk2/scaffold.git
djangorestframework
django-filter