Djangogirls tutorial
[Set server]
1. check installed Django version
>> (myvenv)$ django-admin --version
2. Create project
>> (myvenv)$ django-admin startproject mysite .
3. Modify settings.py for mysite
DEBUG = True
LANGUAGE_CODE = 'en-us'
#TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Saigon'
STATIC_URL = '/static/'
STATIC_ROOT = os.path.join(BASE_DIR, 'static')
4. Migrate
- (myvenv)$ python manage.py migrate
5. Run Server
- (myvenv) D:\DevWeb\djangogirls>python manage.py runserver
Performing system checks...
System check identified no issues (0 silenced).
May 08, 2018 - 13:38:56
Django version 1.11.13, using settings 'mysite.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
[Models - tables]
1. Create App
- (myvenv) $ python manage.py startapp blog
- setting.py --> add installed apps
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'blog',
]
2. define Post class (Database table)
from django.db import models
from django.utils import timezone
# Create your models here.
class Post(models.Model):
author = models.ForeignKey('auth.User')
title = models.CharField(max_length=200)
text = models.TextField()
Created_date = models.DateTimeField(default=timezone.now)
published_date = models.DateTimeField(blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
3. Migrate for app
(myvenv) $ python manage.py makemigrations blog
Migrations for 'blog':
blog\migrations\0001_initial.py
- Create model Post
(myvenv) $ python manage.py migrate blog
Operations to perform:
Apply all migrations: blog
Running migrations:
Applying blog.0001_initial... OK
(myvenv) $
[Use admin mode]
1. connect admin
- http://localhost/admin/
2. create super user
(myvenv) $ python manage.py createsuperuser
Username (leave blank to use 'administrator'): admin
Email address:
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
This password is too common.
Password:
Password (again):
Superuser created successfully.
3. define for use new post object in admin mode
- open blog --> admin.py
- register
from django.contrib import admin
from .models import Post
admin.site.register(Post)
[URL mapping]
1. mysite --> urls.py
from django.conf.urls import url
from django.contrib import admin
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'', include('blog.urls')),
]
django 2.1.1
from django.contrib import admin
from django.urls import path
from django.urls import include
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
2. blog --> urls.py
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.post_list, name='post_list'),
]
django 2.1.1
from django.urls import path
from . import views
urlpatterns = [
path('', views.post_list, name='post_list'),
]
3. blog --> views.py
from django.shortcuts import render
def post_list(request):
pass
django 2.1.1
from django.shortcuts import render
# Create your views here.
def post_list(request):
pass
[Views]
1. define views.py
# Create your views here.
def post_list(request):
return render(request, 'blog/post_list.html', {})
2. create blog/post_list.html file
- location at new folder --> templates\blog\post_list.html
- after restart django server for recognize new folder
3. Query set
- Django shell : 기본적으로 일반 python shell에서는 Django의 데이터를 참조 할 수 없다.
- $ python manage.py shell
>>> from blog.models import Post
>>> Post.objects.all()
<QuerySet [<Post: Test message 001>, <Post: Kim Jong-un believes North Korea sho
uld follow Vietnam’s economic reforms: report>, <Post: Vietnam facing China’s
renewed assertiveness in South China Sea>]>
>>> for post in Post.objects.all():
... print(post)
...
Test message 001
Kim Jong-un believes North Korea should follow Vietnam’s economic reforms: report
Vietnam facing China’s renewed assertiveness in South China Sea
>>>
4. Query Set = Post.objects.all()
>>> qs = Post.objects.all()
>>> print(qs)
<QuerySet [<Post: Test message 001>, <Post: Kim Jong-un believes North Korea sho
uld follow Vietnam’s economic reforms: report>, <Post: Vietnam facing China’s
renewed assertiveness in South China Sea>]>
>>> type(qs)
<class 'django.db.models.query.QuerySet'>
** optional : install ipython (pip install ipython)
5. Create Query Set
- Post.objects.create(author=me, title='Sample title', text='Test')
* author.....
- import User model
In [10]: from django.contrib.auth.models import User
In [11]: User.objects.all()
Out[11]: <QuerySet [<User: admin>]>
In [12]: me = User.objects.first()
In [13]: me.username
Out[13]: 'admin'
In [14]: me.password
Out[14]: 'pbkdf2_sha256$36000$hUPtE7MD2AIv$QBA7Jba0qVaB81gZ3eTqbJXtgouSwQ+rETn8
CGMzQs='
In [15]: Post
Out[15]: blog.models.Post
In [16]: Post.objects.create(author=me, title='Sample Title', text='Test')
Out[16]: <Post: Sample Title>
6. Filtering
- Post.objects.filter(author=me)
- Post.objects.filter(title__contains='title')
- Post.objects.filter(published_date__lte(gte)=timezone.now())
7. Order
- Post.objects.order_by('create_date')
- Post.objects.order_by('-create_date')
8. can combine filter and order and filter again and order again...
[Template Dynamic Data]
1. views.py
from django.shortcuts import render
from django.utils import timezone
from .models import Post
def post_list(request):
# set Query set
qs = Post.objects.all()
qs = qs.filter(published_date__lte=timezone.now())
qs = qs.order_by('published_date')
return render(request, 'blog/post_list.html', {
'post_list':qs,
})
2. post_list.html
<html>
<head>
<title>Django Girls blog</title>
</head>
<body>
<div>
<h1><a href="/">Django Girls Blog</a></h1>
</div>
<hr />
{% for post in post_list %}
<div>
<p>published: {{ post.published_date }}</p>
<h1><a href="">{{ post.title }}</a></h1>
<p>{{ post.text|linebreaksbr }}</p>
</div>
{% endfor %}
</body>
</html>
[CSS]
1. bootstrap
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap-theme.min.css">
2. Static files
- create static folder in blog project folder
djangogirls
├── blog
│ ├── migrations
│ ├── static
│ └── templates
└── mysite
3. blog.css
<link rel="stylesheet" href="<% static "blog/blog.css" %}" >
4. font
<link href="//fonts.googleapis.com/css?family=Lobster&subset=latin,latin-ext" rel="stylesheet" type="text/css">
As before, check the order and place before the link to
blog/static/css/blog.css
. This line will import a font called
Lobster from Google Fonts (
https://www.google.com/fonts).
Find the h1 a
declaration block (the code between braces {
and }
) in the CSS file blog/static/css/blog.css
. Now add the line font-family: 'Lobster';
between the braces, and refresh the page:
h1 a {
color: #FCA205;
font-family: 'Lobster';
}
5. use Class
6. study CSS --> Codeacademy HTML & CSS course
[Template overload]
1. base.html
- define block "block_name"
{% block contents %}
{% endblock %}
2. post_list.html
- define block item
{% extends 'blog/base.html' %}
{% block contents %}
{% for post in post_list %}
<div class="post">
<div class="date">
<p>published: {{ post.published_date }}</p>
</div>
<h2><a href=""> {{ post.title }} </a></h2>
<p>{{ post.text|linebreaks }} </p>
</div>
{% endfor %}
{% endblock %}
[Application extend]
1. Add define URL for post_detail
-- django 2.0 --> update path()
urlpatterns = [
path('', views.post_list, name='post_list'),
#url(r'^post/(?P<pk> \d+)/$', views.post_detail, name='post_detail'),
path('post/<int:pk>/', views.post_detail, name='post_detail'),
]
2. Create post_detail function in veiws class(views.py)
def post_detail(request, pk):
post = get_object_or_404(Post, pk=pk)
return render(request, 'blog/post_detail.html', {
'post': post,
})
3. Define link direction
--> in post_list.html
<h2><a href="{% url 'post_detail' pk=post.pk %}"> {{ post.title }} </a></h2>
4. Create post_detail.html file
{% extends 'blog/base.html' %}
{% block contents %}
<div class="post">
{% if post.published_date %}
<div class="date">
{{ post.published_date }}
</div>
{% endif %}
<h1>{{ post.title }}</h1>
<p>{{ post.text|linebreaksbr }}</p>
</div>
{% endblock %}
[Django Form]
1. Create froms.py
from django import forms
from blog.models import Post
class Postform(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'text']
2. make link button in base.html
<a href="{% url 'post_new' %}" class="top-menu">
<span class="glyphicon glyphicon-plus"></span>
</a>
3. Add url
path('post/new/', views.post_new, name='post_new'),
4. Add simple funcion post_new in views.py
from blog.forms import Postform
def post_new(request):
form = Postform()
return render(request, 'blog/post_edit.html', {
'form' : form,
})
5. Make post_edit.html
{% extends 'blog/base.html' %}
{% block contents %}
<h1>New Post</h1>
<form method="POST" class="post-form">{% csrf_token %}
{{ form.as_p }}
<button type="submit" class="save btn btn-primary">save</button>
</form>
{% endblock %}
6. Modify post_new function for save feature in views.py
def post_new(request):
# request.POST, request.FILES
if request.method == "POST" :
form = Postform(request.POST, request.FILES)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = Postform()
return render(request, 'blog/post_edit.html', {
'form' : form,
})
[Application extend - modify]1. Create post_edit function in views.py
def post_edit(request, pk):
post = get_object_or_404(Post, pk=pk)
if request.method == "POST":
form = Postform(request.POST, request.FILES, instance=post)
if form.is_valid():
post = form.save(commit=False)
post.author = request.user
post.published_date = timezone.now()
post.save()
return redirect('post_detail', pk=post.pk)
else:
form = Postform(instance=post)
return render(request, 'blog/post_edit.html', {
'form': form,
})
2. Add button in post_detail.html
<a class="btn btn-default" href="{% url 'post_edit' pk=post.pk %}">
3. Add url
path('post/<int:pk>/edit/', views.post_edit, name='post_edit'),
4. Auth
{% if user.is_authenticated %}
<a href="{% url 'post_new' %}" class="top-menu">
<span class="glyphicon glyphicon-plus"></span>
</a>
{% endif %}