[PYTHON] Publish DJango page on heroku: Practice

It's been a while, but I will continue with Last time.

By the way, this is what I made. I'm still improving it little by little. http://my-1st-django-blog.herokuapp.com/

After eliminating the addiction

heroku ps:scale web=1

From

heroku open

You can now display the "It worked!" Page. This time I will make a simple blog page from here.

Before you start making

First, enter the virtual environment virtualenv.

source venv/bin/activate

Log in to heroku.

heroku login

This is OK.

Create application

Move to the project directory and create a new application.

python ../manage.py startapp blog_in_heroku

By the way, the directory structure at this stage looks like this (\ __ init__.py and .pyc are omitted).

herokuDir(Procfile,venv,projectDir,manage.py,requirements.txt)
 /projectDir(settings.py,urls.py,wsgi.py)
  /appDir(admin.py,views.py,models.py,tests.py)

I created the application in the project directory simply because I liked it.

Next, add the created application to INSTALLED_APPS.

settings.py ######

INSTALLED_APPS = (
	#…
	'myproject.blog_in_heroku',
)

Also set up the database. It seems that postgreSQL is easy to use on heroku, so feel free to use it. Edit the DATABASES part as follows.

import dj_database_url

DATABASES = {
	'default': {
		'ENGINE':u'django.db.backends.sqlite3',
		'NAME’:’forlocal.sqlite',
	},
}

DATABASES['default'] = dj_database_url.config()	#Comment out when testing locally

Reference: http://momoto.github.io/blog/2013/08/16/deploying-django-1-dot-5-2-on-heroku/ Once sqlite3 is specified, it is for testing in the local environment (in that case, add forlocal.sqlite to .gitignore). Of course, you can write it directly (I think it's better).

Design your application

Set the contents to be saved in the database with models.py in the format of the class.

models.py ######

#..
class Entry(models.Model):
	title = models.CharField(max_length=150)
	body = models.TextField()
	create_date = models.DateTimeField(auto_now_add=True)
	update_date = models.DateTimeField(auto_now=True)

If you want to know what kind of database DJango creates from these models,

python manage.py sql [appname]

You can check the SQL statement automatically generated by this command. However, since the database is created on heroku this time, you can not check it even if you do this on your own PC as it is. If you want to execute a command on heroku, add `` `heroku run``` to the beginning. In other words, it looks like this.

heroku run python manage.py sql [appname]

There are many other things you can do, so it's very convenient to remember.

If so, `` `heroku run python manage.py syncdb``` in the same way. Create a database.

Since I was able to do it without problems, I set URLconf first.

urls.py ######

#..
urlpatterns = patterns('myproject.blog_in_heroku.views',
	 url( r'^$','top_page',name='Blog' ),
	 url( r'^new/$','new',name='New' ),
	 #The name is a little different from the title of the page ...?

This time it's very easy to just top page and post page. If you want to use the administrator page further, review here.

The view looks like this: Create a new form.py in addition to views.py.

forms.py ######

#coding:utf-8
from django import forms

class EntryForm(forms.Form):
	title = forms.CharField(
		label = u'Title',
	)

	body = forms.CharField(
		label = u'Text',
		widget = forms.Textarea(),
	)

Here, I'm using a module called forms from django that didn't appear in Tutorial. CharField probably means `` `<input type =“ text ”> ``` by default. label is the corresponding label. It is also possible to specify the format in Textarea as it is done in body. Import this in views.py and use it.

views.py ######

from django.http import HttpResponse,HttpResponseRedirect
from django.template import loader,RequestContext


def top_page(req):
	from myproject.blog_in_heroku.models import Entry
	rows = Entry.objects.all().order_by('-create_date')

	contexts = RequestContext(req,{
		'rows':rows,
	})
	template = loader.get_template('blog_in_heroku/index.html')
	return HttpResponse( template.render(contexts) )


def new(req):
	from myproject.blog_in_heroku.forms import EntryForm

	if req.method == 'POST':
		form = EntryForm(req.POST)
	else:
		form = EntryForm()

	if form.is_valid():	#Check the input
		from myproject.blog_in_heroku.models import Entry

		new_entry = Entry()

		new_entry.title = form.cleaned_data['title']
		new_entry.body = form.cleaned_data['body']
		# form.cleaned_data['name']The contents are taken out individually from the form

		new_entry.save()

		return HttpResponseRedirect('/')
		#Redirect to top page after posting

	contexts = RequestContext(req,{
		'form':form,
	})

	template = loader.get_template('blog_in_heroku/new.html')

	return HttpResponse( template.render(contexts) )

In general, what you learned in the tutorial is the same as what you are doing. Even though the new function has an unknown method called cleaned_data, I can imagine what I'm doing.

This is the end of page definition. Finally make the actual screen.

Screen making

Write the two templates specified in the view function, index.html and new.html. I also tried using Bootstrap with parentheses. I made it like ``` herokuDir / templates / blog_in_heroku / index.html` ``, but if the templates and below are the same, it doesn't matter where you make it (though it is impossible outside of herokuDir).

index.html ######

<html>
	<head>
		<title>blog</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
		<script src="https://code.jquery.com/jquery.js"></script>
		<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
	</head>

	<body>
		<div class="container">

		{% for row in rows %}
			<p>
				<div>
					<h2>{{ row.title }}</h2>
				</div>
				<div>Posted date{{ row.create_date|date:"Y/m/d" }}</div>
				<div>{{ row.body }}</div>
			</p>
		{% endfor %}
			<a href="/new/">
				<button type="button" class="btn btn-primary">Post!</button>
			</a>

		</div>
	</body>
</html>

new.html ######

<html>
	<head>
		<title>Post</title>
		<meta name="viewport" content="width=device-width, initial-scale=1.0">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css">
		<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap-theme.min.css">
		<script src="https://code.jquery.com/jquery.js"></script>
		<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
	</head>

	<body>
		<div class="container">

			<form role="form" action="" method="post">
			{% csrf_token %}
				<div class="form-group">

					<table><tbody>
					{{form}}
						<tr><td cols="2">
							<input type="submit" class="btn btn-primary" value="Post!" />
							<a href="/">
								<button type="button" class="btn btn-warning">cancel</button>
							</a>
						</td></tr>
					</tbody></table>

				</div>
			</form>

		</div>
	</body>
</html>

On the index page, the contents of the database are extracted one by one with a for statement, as is often the case. In the "Posted date" part{{ row.create_date|date:”Y/m/d” }}There is a description, but in between|"(Pipe) seems to be used when performing simple processing on a template function with a function called a filter. It is unknown at the moment how much processing can be done. Well, this is also a kind because it can be processed on the script side and then passed. It's like a shortcut for.

The form part of the new page is the one defined in the EntryForm class of forms.py written earlier, and it feels like it is materialized here as the form variable of views.py (because of that, the Bootstrap class cannot be attached. It doesn't look cool). Also {% csrf_token%}. To be honest, I don't know what I'm doing with this, but I wrote it for the time being.

Finally, you need to tell DJango where to find the template.

settings.py ######

TEMPLATE_DIRS = (
	'/app/templates',
)

The part corresponding to herokuDir so far is a directory called app on heroku. The following is (probably) easy to understand as it is exactly the same as my environment. By the way, this was confirmed by `` `heroku run pwd``` etc.

Upload to heroku

The rest is flowing

git add .
git commit -m “lets test”
git push heroku master

And start.

heroku ps:scale web=1

If this succeeds, the page is already open. Let's open it.

heroku open

Great fun. It seems that there is no charge for this alone, so let's keep it as it is for a while.

Recommended Posts

Publish DJango page on heroku: Practice
Publish django project developed in Cloud9 on heroku
Django page released on heroku: Preparation my addictive point
Deploy your Django application on Heroku
python + django + scikit-learn + mecab (1) on heroku
Try Ajax on the Django page
python + django + scikit-learn + mecab (2) on heroku
Django blog on heroku: login implementation
Deploy Django api on heroku (personal note)
Deploy the Django app on Heroku [Part 2]
Deploy the Django app on Heroku [Part 1]
Django Heroku Deploy 1
shimehari on heroku
Django Heroku Deploy 2
heroku deployment memo (Django)
Celery notes on Django
Run Django on PythonAnywhere
Publish your Django app on Amazon Linux + Apache + mod_wsgi
Memo of deploying Django × Postgresql on Docker to Heroku
Web App Development Practice: Create a Shift Creation Page with Django! (Experiment on admin page)
Hello World on Django
Miscellaneous notes about deploying the django app on Heroku
Django environment development on Windows 10
Install Django on your Mac
Deploy django project to heroku
Hello World (beginners) on Django
Web App Development Practice: Create a Shift Creation Page with Django! (Shift creation page)
How to deploy a Django app on heroku in just 5 minutes