After we have Python and Django on our environment, why we are not trying to create a project. That will make us easier to understand the basic knowledge in how Django works. This framework is looking different for me, since i’ve been getting familiar with ASP MVC, Laravel or Codeigniter. But when i tried Django, i was thinking wow it’s really out of my mind, i never see the framework like this, usually the MVC framework separated into Model, View, and Controller, but in Django we call controller in views.py. The other thing, in Laravel the views page (html) are using blade engine, therefore you will have html file with extension page.blade.php, either in Rails you will have extension page.html.rb. But in Django you will never see something like that, your html will be html without need to add another extension, and i think it’s cool and very clean.
I have tried to find the tutorial in how to create some project using Django that i think it will make me easier to understand, and finally i found the screencast tutorial on Youtube in how to create Django blog in 16 minutes by Arun Ravindran. Thank’s to Mr. Arun for this awesome tutorial. 😀
But now, the latest version of Django Framework is 1.8.1. And i found that markdown package (wysiwyg plugin) are not working on that. So i decide to change the markdown with CKEditor. Follow the screencast steps, and i’will share you the codes that you need to write.
The Codes :
Take a look the directory place, ensure you are migrating as screencast steps.
Dir file : qblog/urls.py
1 2 3 4 5 6 7 8 |
from django.conf.urls import include, url from django.contrib import admin urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'^ckeditor/', include('ckeditor.urls')), url(r'^', include('blog.urls')), ] |
Dir file : qblog/settings.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
""" Django settings for qblog project. Generated by 'django-admin startproject' using Django 1.9. For more information on this file, see https://docs.djangoproject.com/en/dev/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/dev/ref/settings/ """ import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = '370ndx2v0d67b7kkeyjqzm-$6olbh2%wuzt*31b5@k3+mf8zci' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'blog', 'ckeditor', ] CKEDITOR_UPLOAD_PATH = "uploads/" CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' CKEDITOR_CONFIGS = { 'default': { }, } MIDDLEWARE_CLASSES = [ 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.SessionAuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.security.SecurityMiddleware', ] ROOT_URLCONF = 'qblog.urls' TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': [], 'APP_DIRS': True, 'OPTIONS': { 'context_processors': [ 'django.template.context_processors.debug', 'django.template.context_processors.request', 'django.contrib.auth.context_processors.auth', 'django.contrib.messages.context_processors.messages', ], }, }, ] WSGI_APPLICATION = 'qblog.wsgi.application' # Database # https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } # Internationalization # https://docs.djangoproject.com/en/dev/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/dev/howto/static-files/ STATIC_URL = '/static/' STATIC_ROOT = os.path.join(BASE_DIR, "static") TEMPLATE_DIRS = (os.path.join(BASE_DIR, "templates/blog"), ) STATICFILES_DIRS = (os.path.join(BASE_DIR, "static/client"), ) |
Dir file : blog/urls.py
1 2 3 4 5 6 7 8 |
from django.conf.urls import patterns, include, url from . import views, feed urlpatterns = [ url(r'^$', views.BlogIndex.as_view(), name="index"), url(r'^feed/$', feed.LatestPosts(), name="feed"), url(r'^entry/(?P<slug>\S+)$', views.BlogDetail.as_view(), name="entry_detail"), ] |
Dir file : blog/models.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
from django.db import models from ckeditor.fields import RichTextField from django.core.urlresolvers import reverse class Tag(models.Model): slug = models.SlugField(max_length=200, unique=True) def __str__(self): return self.slug class EntryQuerySet(models.QuerySet): def published(self): return self.filter(publish=True) class Entry(models.Model): title = models.CharField(max_length=200) body = RichTextField() slug = models.SlugField(max_length=200, unique=True) publish = models.BooleanField(default=True) created = models.DateTimeField(auto_now_add=True) modified = models.DateTimeField(auto_now=True) tags = models.ManyToManyField(Tag) objects = EntryQuerySet.as_manager() def get_absolute_url(self): return reverse("entry_detail", kwargs={"slug": self.slug}) def __str__(self): return self.title class Meta: verbose_name = "Blog Entry" verbose_name_plural = "Blog Entries" ordering = ["-created"] |
Dir file : blog/admin.py
1 2 3 4 5 6 7 8 9 |
from django.contrib import admin from . import models class EntryAdmin(admin.ModelAdmin): list_display = ("title", "created") prepopulated_fields = {"slug": ("title",)} admin.site.register(models.Entry, EntryAdmin) admin.site.register(models.Tag) |
Dir file : blog/test.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
from django.test import TestCase from django.contrib.auth import get_user_model from .models import Entry # Create your tests here. class BlogPostTest(TestCase): def setUp(self): self.user = get_user_model().objects.create(username="testuser") def test_create_unpublished(self): entry = Entry(title="Title Me", body=" ", publish=False) entry.save() self.assertEqual(Entry.objects.all().count(), 1) self.assertEqual(Entry.objects.published().count(), 0) entry.publish = True entry.save() self.assertEqual(Entry.objects.published().count(), 1) class BlogViewTests(TestCase): def test_feed_url(self): response = self.client.get('/feed/') self.assertIn("xml", response["Content-Type"]) |
Django CKEditor Installation :
You can follow steps and find the details in this official link.
1st. Open command line and type pip install django-ckeditor-updated.
2nd. Add ckeditor to your INSTALLED_APPS setting.
3th. Add codes below on your settings.py.
1 2 |
CKEDITOR_UPLOAD_PATH = "uploads/" CKEDITOR_JQUERY_URL = '//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js' |
4th. Try to runserver, if you get notice on command line related with import flatatt, open widget.py file under directory C:\Python34\Lib\site-packages\ckeditor then find codes below :
1 |
from django.forms.util import flatatt |
change into this codes :
1 |
from django.forms.utils import flatatt |
Easy right? Run your server to ensure it’s working. You can clone this project from my github account. 🙂
A passionate software engineer who wants to share anything that he learns and some of his life experiences. Want to know more about him? see Fatkhan Fauzi Profile
Nice article Fatkhan! We’ve made creating a blog on Django even easier with Butter (https://buttercms.com). Would love to have you give it a try and share your thoughts.