├── .gitignore ├── LICENSE ├── MANIFEST.in ├── README.rst ├── TODO ├── requirements.txt ├── setup.py └── simpleblog ├── __init__.py ├── admin.py ├── forms.py ├── locale ├── fr_FR │ └── LC_MESSAGES │ │ ├── django.mo │ │ └── django.po └── sv_SE │ └── LC_MESSAGES │ ├── django.mo │ └── django.po ├── migrations ├── 0001_initial.py └── __init__.py ├── models.py ├── settings.py ├── signals.py ├── templates ├── simpleblog │ ├── includes │ │ └── post_form.html │ ├── post_archive.html │ ├── post_archive_page.html │ ├── post_detail.html │ ├── post_detail_page.html │ ├── post_list.html │ └── post_list_page.html └── tags │ └── latest_blog_posts.html ├── templatetags ├── __init__.py └── blog_tags.py ├── tests.py ├── urls.py └── views.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | build 3 | dist 4 | *egg-info 5 | .idea 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Jesper Håkansson and individual contributors. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are 5 | permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this list of 8 | conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 11 | of conditions and the following disclaimer in the documentation and/or other materials 12 | provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 15 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 16 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 18 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 19 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 20 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 21 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 23 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE 2 | include README.rst 3 | include requirements.txt 4 | recursive-include simpleblog/templates * 5 | recursive-include simpleblog/templatetags * 6 | recursive-include simpleblog/locale * 7 | recursive-include simpleblog/migrations * -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ========================== 2 | django-simple-blog 3 | ========================== 4 | 5 | What is it? 6 | =========== 7 | 8 | django-simple-blog is a simple Django app for fast integrating your 9 | current project with a blog-system 10 | 11 | You can easily write blog posts, let users comment the posts if you'd like to. 12 | 13 | Installation 14 | ============ 15 | 16 | You can do any of the following to install ``django-simple-blog`` 17 | 18 | - Run ``pip install django-simple-blog``. 19 | - Run ``easy_install django-simple-blog``. 20 | - Download or "git clone" the package and run ``setup.py``. 21 | - Download or "git clone" the package and add ``simpleblog`` to your PYTHONPATH. 22 | 23 | 24 | Usage 25 | ===== 26 | 27 | 1. Add ``simpleblog`` and `django.contrib.sites` to your INSTALLED_APPS setting like this:: 28 | 29 | INSTALLED_APPS = [ 30 | ... 31 | 'django.contrib.sites', 32 | 'simpleblog', 33 | ] 34 | 35 | 36 | Note: if you want to customize the templates, please add ``el_pagination`` ``markdown_deux`` ``pagedown`` to your INSTALLED_APPS setting. 37 | 38 | INSTALLED_APPS = [ 39 | ... 40 | 'django.contrib.sites', 41 | 'el_pagination', 42 | 'markdown_deux', 43 | 'pagedown', 44 | 'simpleblog', 45 | ] 46 | 2. Add `SITE_ID = 1` in your settings.py. 47 | 3. Run ``python manage.py migrate`` 48 | 4. Include the ``simpleblog urls`` like this to have your "home page" as the blog index:: 49 | 50 | ... 51 | 52 | urlpatterns =[ 53 | path('admin/', admin.site.urls), 54 | path('blog/', include('simpleblog.urls')), 55 | ] 56 | 57 | Settings 58 | ======== 59 | ``django-simple-blog`` has one setting at the moment:: 60 | 61 | # How long the length of the textarea should be. 62 | 63 | MAX_LENGTH_TEXTAREA = 120 #(defaults to None) 64 | 65 | 66 | Templatetags 67 | =========== 68 | 69 | ``django-simple-blog`` comes with one templatetag for getting 70 | the latest desired number of posts. Just do this in any template:: 71 | {% load blog_tags %} 72 | 73 | {% latest_blog_posts 5 %} 74 | 75 | 76 | Translation 77 | =========== 78 | 79 | ``django-simple-blog`` is available in ``english``, ``swedish`` and ``french`` 80 | at the moment, feel free to translate the application in another 81 | language. 82 | 83 | Admin 84 | ===== 85 | For writing posts we will use django's admin application. 86 | 87 | The templates 88 | ============= 89 | 90 | The templates is just there as examples for how your templates 91 | could look like, but they work excellent as well, but if you don't 92 | like them, just override them with your own templates simply. 93 | 94 | Requirements 95 | ============ 96 | 97 | `Django>=1.8 98 | `_ 99 | 100 | `django-el-paginatio>=2.0 101 | `_ 102 | 103 | `simplemathcaptcha>=1.0.3 104 | `_ 105 | 106 | `django-markdown-deux>=1.0.4 107 | `_ 108 | 109 | `django-pagedown>=0.0.5 110 | `_ 111 | 112 | If you have problem getting the right versions of these packages, 113 | clone them from their github repository. 114 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | # Create our own tags so rendering posts/comments follows DRY 2 | 3 | # Pagedown: enforce comment max length 4 | 5 | # Pagedown: can we display editor and preview side-by-side? (would look better 6 | in admin dashboard) 7 | 8 | # Pagedown: left-align comment editor 9 | 10 | # Make blog post content (not comments) unsafe so the author can include HTML 11 | tags 12 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | Django>=1.8 2 | django-el-pagination==3.0.1 3 | django-simple-math-captcha>=1.0.3 4 | django-markdown-deux>=1.0.4 5 | django-pagedown>=0.0.5 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | from setuptools import setup 4 | 5 | version = __import__('simpleblog').get_version() 6 | 7 | f = open(os.path.join(os.path.dirname(__file__), 'README.rst')) 8 | readme = f.read() 9 | f.close() 10 | 11 | 12 | def read(fname): 13 | try: 14 | return open(os.path.join(os.path.dirname(__file__), fname)).read() 15 | except IOError: 16 | return '' 17 | 18 | setup( 19 | name = 'django-simple-blog', 20 | version = version, 21 | packages = ['simpleblog'], 22 | include_package_data = True, 23 | install_requires = [line for line in read('requirements.txt').split('\n') 24 | if line and not line.startswith('#')], 25 | license = 'BSD License', 26 | description = 'An easy way to start writing blog posts.', 27 | long_description = readme, 28 | url = 'https://github.com/Drager/django-simple-blog', 29 | author = 'Drager', 30 | author_email = 'drager@programmers.se', 31 | classifiers = [ 32 | 'Environment :: Web Environment', 33 | 'Framework :: Django', 34 | 'Intended Audience :: Developers', 35 | 'License :: OSI Approved :: BSD License', 36 | 'Programming Language :: Python', 37 | 'Programming Language :: Python :: 2.6', 38 | 'Programming Language :: Python :: 2.7', 39 | 'Programming Language :: Python :: 3.4', 40 | 'Programming Language :: Python :: 3.5', 41 | 'Topic :: Internet :: WWW/HTTP', 42 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content', 43 | ], 44 | ) 45 | -------------------------------------------------------------------------------- /simpleblog/__init__.py: -------------------------------------------------------------------------------- 1 | VERSION = (0, 3, 0) 2 | 3 | 4 | def get_version(): 5 | """Return the Django Simple Blog version as a string.""" 6 | return '.'.join(map(str, VERSION)) 7 | -------------------------------------------------------------------------------- /simpleblog/admin.py: -------------------------------------------------------------------------------- 1 | from django.contrib import admin 2 | from django.db import models as django_models 3 | from pagedown.widgets import AdminPagedownWidget 4 | 5 | from . import models 6 | 7 | 8 | class PostAdmin(admin.ModelAdmin): 9 | # Note: this makes pagedown the default editor for ALL text fields 10 | formfield_overrides = { 11 | django_models.TextField: {'widget': AdminPagedownWidget }, 12 | } 13 | prepopulated_fields = {'slug': ('title',)} 14 | list_display = ('title', 'post_date', 'posted_by', 15 | 'comment_count', 'allow_comments') 16 | readonly_fields = ('comment_count',) 17 | 18 | 19 | class CommentAdmin(admin.ModelAdmin): 20 | # Note: this makes pagedown the default editor for ALL text fields 21 | formfield_overrides = { 22 | django_models.TextField: {'widget': AdminPagedownWidget }, 23 | } 24 | list_display = ('user_name', 'user_email', 'ip_address', 'post_date') 25 | 26 | admin.site.register(models.Post, PostAdmin) 27 | admin.site.register(models.Comment, CommentAdmin) 28 | -------------------------------------------------------------------------------- /simpleblog/forms.py: -------------------------------------------------------------------------------- 1 | from random import choice, randint 2 | 3 | from django import forms 4 | from django.utils.safestring import mark_safe 5 | from django.utils.translation import ugettext_lazy as _ 6 | from pagedown.widgets import PagedownWidget 7 | from simplemathcaptcha.fields import MathCaptchaField 8 | 9 | from .models import Comment 10 | from .settings import MAX_LENGTH_TEXTAREA 11 | 12 | 13 | class UserCommentForm(forms.ModelForm): 14 | error_msg = _( 15 | 'Cannot be empty nor only contain spaces. Please fill in the field.') 16 | 17 | bodytext = forms.CharField(widget=PagedownWidget()) 18 | 19 | class Meta: 20 | model = Comment 21 | fields = ["bodytext"] 22 | if MAX_LENGTH_TEXTAREA is not None: 23 | widgets = { 24 | 'bodytext': forms.Textarea(attrs={'maxlength': MAX_LENGTH_TEXTAREA}) 25 | } 26 | 27 | def clean_bodytext(self): 28 | bodytext = self.cleaned_data.get('bodytext') 29 | if bodytext: 30 | if not bodytext.strip(): 31 | raise forms.ValidationError(self.error_msg) 32 | return bodytext 33 | 34 | 35 | class CommentForm(UserCommentForm): 36 | user_name = forms.CharField(label=_('Username'), initial=_('anonymous')) 37 | user_email = forms.EmailField(label=_('E-mail'), required=False) 38 | # captcha = MathCaptchaField( 39 | # required=True, error_messages={'invalid': _('Welcome robot')}) 40 | 41 | class Meta: 42 | model = Comment 43 | fields = ("user_name", "user_email", "bodytext") 44 | if MAX_LENGTH_TEXTAREA is not None: 45 | widgets = { 46 | 'bodytext': forms.Textarea(attrs={'maxlength': MAX_LENGTH_TEXTAREA}) 47 | } 48 | 49 | def clean_user_name(self): 50 | self.error_msg 51 | user_name = self.cleaned_data.get('user_name') 52 | if user_name: 53 | if not user_name.strip(): 54 | raise forms.ValidationError(self.error_msg) 55 | return user_name 56 | -------------------------------------------------------------------------------- /simpleblog/locale/fr_FR/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drager/django-simple-blog/289e910bdd9d5948ec79cff36e4bc906bf7f2601/simpleblog/locale/fr_FR/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /simpleblog/locale/fr_FR/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # French translation of this blog. 2 | # Copyright (C) 2017 3 | # This file is distributed under the same license as the django-simple-blog package. 4 | # Florimond Manca , 2017. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2017-12-10 11:22+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: Florimond Manca \n" 14 | "Language-Team: Florimond Manca \n" 15 | "Language: French\n" 16 | "MIME-Version: 1.0\n" 17 | "Content-Type: text/plain; charset=UTF-8\n" 18 | "Content-Transfer-Encoding: 8bit\n" 19 | 20 | #: forms.py:15 21 | msgid "Cannot be empty nor only contain spaces. Please fill in the field." 22 | msgstr "Ce champ ne peut pas être vide ou ne contenir que des espaces, veuillez le remplir." 23 | 24 | #: forms.py:36 25 | msgid "Username" 26 | msgstr "Nom d'utilisateur" 27 | 28 | #: forms.py:36 29 | msgid "anonymous" 30 | msgstr "anonyme" 31 | 32 | #: forms.py:37 33 | msgid "E-mail" 34 | msgstr "Adresse électronique" 35 | 36 | #: forms.py:39 37 | msgid "Welcome robot" 38 | msgstr "Bienvenue, robot" 39 | 40 | #: models.py:15 41 | msgid "title" 42 | msgstr "titre" 43 | 44 | #: models.py:17 models.py:53 45 | msgid "message" 46 | msgstr "contenu" 47 | 48 | #: models.py:20 models.py:56 49 | msgid "post date" 50 | msgstr "publié le" 51 | 52 | #: models.py:21 53 | msgid "modified" 54 | msgstr "modifié le" 55 | 56 | #: models.py:23 57 | msgid "posted by" 58 | msgstr "publié par" 59 | 60 | #: models.py:26 61 | msgid "allow comments" 62 | msgstr "autoriser les commentaires" 63 | 64 | #: models.py:28 65 | msgid "comment count" 66 | msgstr "nombre de commentaires" 67 | 68 | #: models.py:31 models.py:52 69 | msgid "post" 70 | msgstr "billet" 71 | 72 | #: models.py:32 73 | msgid "posts" 74 | msgstr "billets" 75 | 76 | #: models.py:58 77 | msgid "ip address" 78 | msgstr "adresse IP" 79 | 80 | #: models.py:62 81 | msgid "user" 82 | msgstr "utilisateur" 83 | 84 | #: models.py:64 85 | msgid "user name" 86 | msgstr "nom d'utilisateur" 87 | 88 | #: models.py:65 89 | msgid "user email" 90 | msgstr "email utilisateur" 91 | 92 | #: models.py:71 93 | msgid "comment" 94 | msgstr "commentaire" 95 | 96 | #: models.py:72 97 | msgid "comments" 98 | msgstr "commentaires" 99 | -------------------------------------------------------------------------------- /simpleblog/locale/sv_SE/LC_MESSAGES/django.mo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drager/django-simple-blog/289e910bdd9d5948ec79cff36e4bc906bf7f2601/simpleblog/locale/sv_SE/LC_MESSAGES/django.mo -------------------------------------------------------------------------------- /simpleblog/locale/sv_SE/LC_MESSAGES/django.po: -------------------------------------------------------------------------------- 1 | # Swedish translation of this blog. 2 | # Copyright (C) 2014 3 | # This file is distributed under the same license as the django-simple-blog package. 4 | # Jesper Håkansson , 2014. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: \n" 11 | "POT-Creation-Date: 2014-02-05 13:14+0100\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: Jesper Håkansson \n" 14 | "Language-Team: Jesper Håkansson 8 | {% csrf_token %} 9 | {% for field in comment_form %} 10 |
11 | {{ field.errors }} 12 | 13 | {{ field.label_tag }} 14 |
15 | {{ field }} 16 | 17 |
18 | {% endfor %} 19 |

20 | 21 |

22 | -------------------------------------------------------------------------------- /simpleblog/templates/simpleblog/post_archive.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 |
5 |

Blog archive

6 |
7 | {% include page_template %} 8 | {% endblock %} 9 | -------------------------------------------------------------------------------- /simpleblog/templates/simpleblog/post_archive_page.html: -------------------------------------------------------------------------------- 1 | {% load el_pagination_tags %} 2 | 3 | {% if posts %} 4 | {% paginate posts %} 5 | 6 | {% for post in posts %} 7 | 27 |
28 | {% endfor %} 29 | 30 | {% show_more "Load more blog posts" %} 31 | 32 | {% else %} 33 |

There's no blog entries...

34 | {% endif %} 35 | -------------------------------------------------------------------------------- /simpleblog/templates/simpleblog/post_detail.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% load markdown_deux_tags %} 4 | 5 | {% block content %} 6 | 7 | 35 | 36 | 37 |

Comment

38 | {% if post.allow_comments %} 39 | {% include 'simpleblog/includes/post_form.html' %} 40 |
41 |

Comments

42 | 43 | {% include page_template %} 44 | 45 | {% else %} 46 |

Comments are disabled for this post.

47 | {% endif %} 48 | 49 | {% endblock %} 50 | -------------------------------------------------------------------------------- /simpleblog/templates/simpleblog/post_detail_page.html: -------------------------------------------------------------------------------- 1 | {% load el_pagination_tags %} 2 | {% load markdown_deux_tags %} 3 | 4 | {% if comments %} 5 | {% paginate comments %} 6 | {% for comment in comments %} 7 |
8 |
9 |
10 | {{ comment.user_name }} 11 | 14 |
15 | 16 | {{ comment.bodytext|markdown }} 17 | 18 |
19 |
20 |
21 | {% endfor %} 22 | 23 | {% show_more "Load more comments" %} 24 | 25 | {% else %} 26 |

There's no comments...

27 | {% endif %} 28 | -------------------------------------------------------------------------------- /simpleblog/templates/simpleblog/post_list.html: -------------------------------------------------------------------------------- 1 | {% extends 'base.html' %} 2 | 3 | {% block content %} 4 | 5 | {% include page_template %} 6 | 7 | {% endblock %} 8 | -------------------------------------------------------------------------------- /simpleblog/templates/simpleblog/post_list_page.html: -------------------------------------------------------------------------------- 1 | {% load el_pagination_tags %} 2 | 3 | {% load markdown_deux_tags %} 4 | 5 | {% if posts %} 6 | {% paginate posts %} 7 | 8 | {% for post in posts %} 9 | 37 | {% endfor %} 38 | 39 | {% show_more "Load more blog posts" %} 40 | 41 | {% else %} 42 |

There's no blog entries...

43 | {% endif %} 44 | -------------------------------------------------------------------------------- /simpleblog/templates/tags/latest_blog_posts.html: -------------------------------------------------------------------------------- 1 | {% load humanize %} 2 | 3 |
4 |
5 |

Recent posts

6 |
7 |
    8 | {% for latest_blog_post in latest_blog_posts %} 9 |
  • 10 | 11 |

    {{ latest_blog_post }}

    12 |
    13 | - {{ latest_blog_post.post_date|naturaltime }} 14 |
  • 15 | {% endfor %} 16 |
17 |
18 | -------------------------------------------------------------------------------- /simpleblog/templatetags/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drager/django-simple-blog/289e910bdd9d5948ec79cff36e4bc906bf7f2601/simpleblog/templatetags/__init__.py -------------------------------------------------------------------------------- /simpleblog/templatetags/blog_tags.py: -------------------------------------------------------------------------------- 1 | from django import template 2 | 3 | from ..models import Post 4 | 5 | register = template.Library() 6 | 7 | 8 | def latest_blog_posts(context, num): 9 | """ 10 | Displays the most recent blog posts. It takes an argument, num 11 | and displays so many posts depending on the value. 12 | """ 13 | latest_blog_posts = Post.objects.all()[:num].select_related() 14 | 15 | return { 16 | 'latest_blog_posts': latest_blog_posts 17 | } 18 | 19 | register.inclusion_tag('tags/latest_blog_posts.html', 20 | takes_context=True)(latest_blog_posts) 21 | -------------------------------------------------------------------------------- /simpleblog/tests.py: -------------------------------------------------------------------------------- 1 | """ 2 | This file demonstrates writing tests using the unittest module. These will pass 3 | when you run "manage.py test". 4 | 5 | Replace this with more appropriate tests for your application. 6 | """ 7 | 8 | from django.test import TestCase 9 | 10 | 11 | class SimpleTest(TestCase): 12 | 13 | def test_basic_addition(self): 14 | """ 15 | Tests that 1 + 1 always equals 2. 16 | """ 17 | self.assertEqual(1 + 1, 2) 18 | -------------------------------------------------------------------------------- /simpleblog/urls.py: -------------------------------------------------------------------------------- 1 | from django.urls import re_path 2 | 3 | from .views import BlogDetailView, BlogListView, LatestEntriesFeed 4 | 5 | urlpatterns = [ 6 | re_path(r'^(?P\d{4})/(?P\d{2})/(?P\d{2})/(?P[-_\w]+)/$', 7 | BlogDetailView.as_view(), 8 | name='blog_detail', 9 | ), 10 | re_path(r'^archive/$', 11 | BlogListView.as_view( 12 | template_name="simpleblog/post_archive.html", 13 | page_template="simpleblog/post_archive_page.html"), 14 | name="blog_archive"), 15 | re_path(r'^latest/feed/$', LatestEntriesFeed()), 16 | re_path(r'^$', BlogListView.as_view(), name='blog_index'), 17 | ] 18 | -------------------------------------------------------------------------------- /simpleblog/views.py: -------------------------------------------------------------------------------- 1 | from django.contrib.sites.models import Site 2 | from django.contrib.syndication.views import Feed 3 | from django.shortcuts import redirect 4 | from django.views.generic.dates import DateDetailView 5 | from el_pagination.views import AjaxListView 6 | 7 | from .forms import CommentForm, UserCommentForm 8 | from .models import Comment, Post 9 | 10 | 11 | class LatestEntriesFeed(Feed): 12 | title = "%s blog entries" % (Site.objects.get_current()) 13 | description = "The latest blog entries" 14 | link = "/siteposts/" 15 | 16 | def items(self): 17 | return Post.objects.order_by('-post_date')[:5] 18 | 19 | def item_title(self, item): 20 | return item.title 21 | 22 | def item_description(self, item): 23 | return item.bodytext 24 | 25 | 26 | class BlogListView(AjaxListView): 27 | context_object_name = "posts" 28 | queryset = Post.objects.all().select_related() 29 | 30 | 31 | class BlogDetailView(DateDetailView): 32 | model = Post 33 | date_field = 'post_date' 34 | month_format = '%m' 35 | page_template = "simpleblog/post_detail_page.html" 36 | 37 | def get_queryset(self): 38 | queryset = super(BlogDetailView, self).get_queryset() 39 | return queryset.select_related() 40 | 41 | def post(self, request, *args, **kwargs): 42 | self.object = post = self.get_object() 43 | if request.user.is_authenticated: 44 | form = UserCommentForm(request.POST) 45 | else: 46 | form = CommentForm(request.POST) 47 | if form.is_valid(): 48 | comment = form.save(commit=False) 49 | comment.post = post 50 | if request.user.is_authenticated: 51 | comment.user = request.user 52 | comment.user_name = request.user 53 | comment.user_email = request.user.email 54 | comment.ip = '0.0.0.0' 55 | comment.save() 56 | return redirect(post.get_absolute_url()) 57 | context = self.get_context_data(object=post) 58 | context['comment_form'] = form 59 | return self.render_to_response(context) 60 | 61 | def get_context_data(self, **kwargs): 62 | if self.request.user.is_authenticated: 63 | form = UserCommentForm() 64 | else: 65 | form = CommentForm() 66 | context = { 67 | 'page_template': self.page_template, 68 | 'comment_form': form, 69 | 'comments': Comment.objects.filter(post=self.object.id).select_related() 70 | } 71 | return super(BlogDetailView, self).get_context_data(**context) 72 | 73 | def render_to_response(self, context, **response_kwargs): 74 | """ 75 | Returns a response with a template depending if the request is ajax 76 | or not and it renders with the given context. 77 | """ 78 | if self.request.is_ajax(): 79 | template = self.page_template 80 | else: 81 | template = self.get_template_names() 82 | return self.response_class( 83 | request=self.request, 84 | template=template, 85 | context=context, 86 | **response_kwargs 87 | ) 88 | --------------------------------------------------------------------------------