Skip to content
This repository was archived by the owner on May 23, 2020. It is now read-only.

Commit 9ab7d4e

Browse files
committed
Added feature JSON post view
1 parent df03b35 commit 9ab7d4e

File tree

5 files changed

+65
-37
lines changed

5 files changed

+65
-37
lines changed

CHANGELOG.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
### v.3.7
2+
* Added feature blog post json format: `<post_url>/?format=json`
3+
4+
```
5+
curl -X GET \
6+
-H "Accept: application/json" \
7+
https://python.web.id/blog/django-redirect-http-to-https/?format=json
8+
```
9+
10+
* Update for fixed draft post
11+
112
### v.3.6
213
* Added feature auto backup to the json file
314
* Added feature highlight pre
@@ -7,12 +18,12 @@
718
### v.3.5
819
* Implement Standard [PEP8](https://www.python.org/dev/peps/pep-0008/) for Python.
920
* Implement CBV (Class Bassed View).
10-
* Migrated to [Python 3.5](https://docs.python.org/3/)
11-
* Migrated to [Django 1.10](https://docs.djangoproject.com/en/1.10/)
21+
* Migrated from Python 2.7 to [Python 3.5](https://docs.python.org/3/)
22+
* Migrated from Djagno 1.8 to [Django 1.10](https://docs.djangoproject.com/en/1.10/)
1223
* Migrated [Django wp-admin](https://github.com/barszczmm/django-wpadmin) to [Django suit](https://github.com/darklow/django-suit).
1324
* Migrated [Django Ckeditor](https://github.com/django-ckeditor/django-ckeditor) to [Django Redactor](https://github.com/douglasmiranda/django-wysiwyg-redactor).
1425
* Added [Django nocaptcha recaptcha](https://github.com/ImaginaryLandscape/django-nocaptcha-recaptcha) for contact form.
15-
* Added Page for tranding posts by visit.
26+
* Added Page for tranding posts by visitor.
1627
* Added Feature export and import using [Django Import Export](https://github.com/django-import-export/django-import-export)
1728
* Changed Gallery Upload to only once attachment field.
1829
* Added custom template for Error page, Maintenance mode, and much more...

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Django-Blog-Python-Learning
22
-------
33

4-
Release Source Code of Django Blog Python Learning v.3.6
4+
Release Source Code of Django Blog Python Learning v.3.7
55

66
### Demo:
77
- [https://python.web.id](https://python.web.id)
@@ -21,6 +21,7 @@ Release Source Code of Django Blog Python Learning v.3.6
2121
- About author in the botom of posts.
2222
- Visitor Counter
2323
- Auto backup to the json file
24+
- Json post view
2425
- much more...
2526

2627
### Instalation

blog/models.py

Lines changed: 6 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -65,19 +65,7 @@ class Post(TimeStampedModel):
6565
null=True,
6666
blank=True,
6767
help_text='Optional cover post')
68-
description = RedactorField(
69-
allow_file_upload=False,
70-
redactor_options={
71-
'lang': 'en',
72-
'focus': 'true',
73-
'buttons': [
74-
'formatting', 'bold', 'italic',
75-
'unorderedlist', 'orderedlist', 'outdent',
76-
'indent', 'image', 'link', 'alignment',
77-
'horizontalrule',
78-
]
79-
}
80-
)
68+
description = RedactorField()
8169
tags = models.ManyToManyField('Tag')
8270
keywords = models.CharField(max_length=200, null=True, blank=True,
8371
help_text='Keywords sparate by comma.')
@@ -89,6 +77,10 @@ class Post(TimeStampedModel):
8977
def get_absolute_url(self):
9078
return reverse('detail_post_page', kwargs={'slug': self.slug})
9179

80+
@property
81+
def total_visitors(self):
82+
return Visitor.objects.filter(post__pk=self.pk).count()
83+
9284
def __str__(self):
9385
return self.title
9486

@@ -102,19 +94,7 @@ class Page(TimeStampedModel):
10294
author = models.ForeignKey(Author, related_name='author_page')
10395
title = models.CharField(max_length=200)
10496
slug = models.SlugField(max_length=200, unique=True)
105-
description = RedactorField(
106-
allow_file_upload=False,
107-
redactor_options={
108-
'lang': 'en',
109-
'focus': 'true',
110-
'buttons': [
111-
'formatting', 'bold', 'italic',
112-
'unorderedlist', 'orderedlist', 'outdent',
113-
'indent', 'image', 'link', 'alignment',
114-
'horizontalrule',
115-
]
116-
}
117-
)
97+
description = RedactorField()
11898
publish = models.BooleanField(default=True)
11999

120100
def __str__(self):

blog/templates/blog/blog_home.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
{% for object in object_list %}
88
<div class="post">
9-
<h2 class="title__bold"><a href="{% url 'detail_post_page' slug=object.slug %}">{{ object.title }}</a></h2>
9+
<h2><a href="{% url 'detail_post_page' slug=object.slug %}">{{ object.title }}</a></h2>
1010
<p class="meta">
1111
By: <a href="{% url 'author_posts_page' username=object.author.user.username %}" style="text-transform:uppercase">{{ object.author }}</a> &#9679;
1212
at {{ object.created }} &#9679;

blog/views.py

Lines changed: 42 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import time
22
import datetime
33
import socket
4+
import json
5+
46
from django.views import generic
57
from django.http import HttpResponse
68
from django.shortcuts import (render, render_to_response, redirect, get_object_or_404)
@@ -72,9 +74,14 @@ def get_client_ip(self):
7274

7375
def visitorCounter(self):
7476
try:
75-
Visitor.objects.get(post=self.object, ip=self.request.META['REMOTE_ADDR'])
77+
Visitor.objects.get(
78+
post=self.object,
79+
ip=self.request.META['REMOTE_ADDR']
80+
)
7681
except ObjectDoesNotExist:
77-
dns = str(socket.getfqdn(self.request.META['REMOTE_ADDR'])).split('.')[-1]
82+
dns = str(socket.getfqdn(
83+
self.request.META['REMOTE_ADDR']
84+
)).split('.')[-1]
7885
try:
7986
# trying for localhost: str(dns) == 'localhost',
8087
# trying for production: int(dns)
@@ -92,10 +99,39 @@ def visitorCounter(self):
9299

93100
def dispatch(self, request, *args, **kwargs):
94101
obj = self.get_object()
95-
if obj.publish == False and \
96-
request.user.is_anonymous() or \
97-
request.user != obj.author.user:
98-
return redirect('homepage')
102+
if obj.publish == False:
103+
if request.user.is_anonymous() or \
104+
request.user != obj.author.user:
105+
return redirect('homepage')
106+
elif request.GET.get('format') == 'json':
107+
get_cover = lambda obj: None if obj.cover == None \
108+
or obj.cover == '' \
109+
else 'https://{0}{1}{2}'.format(
110+
request.get_host(),
111+
settings.MEDIA_URL,
112+
obj.cover
113+
)
114+
data = dict(
115+
title=obj.title,
116+
url='https://{0}/blog/{1}'.format(
117+
request.get_host(),
118+
obj.slug
119+
),
120+
cover=get_cover(obj),
121+
author=obj.author.user.username,
122+
created=str(obj.created)[:19],
123+
modified=str(obj.modified)[:19],
124+
tags=[
125+
{'title': t.title, 'slug': t.slug}
126+
for t in obj.tags.all()
127+
],
128+
description=obj.description,
129+
visitors=obj.total_visitors
130+
)
131+
return HttpResponse(
132+
json.dumps(data),
133+
content_type='application/json'
134+
)
99135
else:
100136
return super(DetailPostView, self).dispatch(
101137
request, *args, **kwargs

0 commit comments

Comments
 (0)