refer:
docs:
With Django, you can take Web applications from concept to launch in a matter of hours. Django takes care of much of the hassle of Web development, so you can focus on writing your app without needing to reinvent the wheel. It’s free and open source.
latest official version: 1.8 Previous releases
Unsupported previous releases (no longer receive security updates or bug fixes):
⇒ You should use version 1.7.7
Go to django source and run below commands:
set PATH=%PATH%;"d:\tools\Python27" python setup.py install
→ recheck:
/usr/lib/python2.7/site-packages (Unix, Python 2.7) d:\tools\Python27\Lib\site-packages\Django-xxx (Windows)
pip install Django==1.8
python -c "import django; print(django.get_version())"
⇒ output:
1.8
(Linux: Put your code in some directory outside of the document root, such as /home/mycode)
windows:
d:\tools\Python27\Scripts\django-admin.exe startproject mysite
linux:
django-admin.py startproject mysite
cd mysite python manage.py runserver python manage.py runserver 8080 -> run another port
Why create virtual environment?Because with each django source, they compatible with each other version of django, so you must create the virtual enviornment for that version of django and not affect the other django source which run other django version
pip install virtualenv
virtualenv django1.8 django1.8\Scripts\activate pip install Django==1.8
django-admin startproject mysite cd mysite python manage.py runserver
[mysite/settings.py] INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', )
python manage.py syncdb -> The syncdb command looks at the INSTALLED_APPS setting and creates any necessary database tables according to the database settings in your file
python manage.py startapp polls
from django.db import models # Create your models here. class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') class Choice(models.Model): question = models.ForeignKey(Question) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0)
[mysite/settings.py]
INSTALLED_APPS = ( .................. 'polls', )
python manage.py makemigrations
output:
Migrations for 'polls': 0001_initial.py: - Create model Question - Create model Choice
python manage.py syncdb
edit [mysite\polls\admin.py]
from polls.models import Question # Register your models here. admin.site.register(Question)
refer: https://docs.djangoproject.com/en/1.7/intro/tutorial03/
from django.shortcuts import render from django.http import HttpResponse # Create your views here. def index(request): return HttpResponse("Hello, world. You're at the polls index.")
polls/ __init__.py admin.py models.py tests.py urls.py views.py
from django.conf.urls import patterns, url from polls import views urlpatterns = patterns('', url(r'^$', views.index, name='index'), )
from django.conf.urls import patterns, include, url from django.contrib import admin urlpatterns = patterns('', # Examples: # url(r'^$', 'firstdjango.views.home', name='home'), # url(r'^blog/', include('blog.urls')), url(r'^polls/', include('polls.urls')), url(r'^admin/', include(admin.site.urls)), )
python manage.py inspectdb
refer:
A template is simply a text file. It can generate any text-based format (HTML, XML, CSV, etc.).
A template contains variables, which get replaced with values when the template is evaluated, and tags, which control the logic of the template:
{{ variable }}
. For example:
{{ section.title }}
Below is a minimal template that illustrates a few basics. Each element will be explained later in this document.
{% extends "base_generic.html" %} {% block title %}{{ section.title }}{% endblock %} {% block content %} <h1>{{ section.title }}</h1> {% for story in story_list %} <h2> <a href="{{ story.get_absolute_url }}"> {{ story.headline|upper }} </a> </h2> <p>{{ story.tease|truncatewords:"100" }}</p> {% endfor %} {% endblock %}
Basic example for template inheritance:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>{% block title %}My amazing site{% endblock %}</title> </head> <body> <div id="sidebar"> {% block sidebar %} <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> {% endblock %} </div> <div id="content"> {% block content %}{% endblock %} </div> </body> </html>
{% extends "base.html" %} {% block title %}My amazing blog{% endblock %} {% block content %} {% for entry in blog_entries %} <h2>{{ entry.title }}</h2> <p>{{ entry.body }}</p> {% endfor %} {% endblock %}
At that point, the template engine will notice the three block tags in base.html and replace those blocks with the contents of the child template. Depending on the value of blog_entries, the output might look like:
<!DOCTYPE html> <html lang="en"> <head> <link rel="stylesheet" href="style.css" /> <title>My amazing blog</title> </head> <body> <div id="sidebar"> <ul> <li><a href="/">Home</a></li> <li><a href="/blog/">Blog</a></li> </ul> </div> <div id="content"> <h2>Entry one</h2> <p>This is my first entry.</p> <h2>Entry two</h2> <p>This is my second entry.</p> </div> </body> </html>
Mezzanine makes use of as few libraries as possible (apart from a standard Django environment), with the following dependencies:
⇒ Auto install these dependencies when we install mezzanine
Install on windows:
easy_install.exe mezzanine
Install on linux:
pip install mezzanine
mezzanine-project mezzcms
python manage.py syncdb
python manage.py runserver
INSTALLED_APPS = ( "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.redirects", "django.contrib.sessions", "django.contrib.sites", "django.contrib.sitemaps", "django.contrib.staticfiles", "mezzanine.boot", "mezzanine.conf", "mezzanine.core", "mezzanine.generic", "mezzanine.blog", "mezzanine.forms", "mezzanine.pages", "mezzanine.galleries", "mezzanine.twitter", #"mezzanine.accounts", #"mezzanine.mobile", )
with mezzaine apps
"mezzanine.boot", "mezzanine.conf", "mezzanine.core", "mezzanine.generic", "mezzanine.blog", "mezzanine.forms", "mezzanine.pages", "mezzanine.galleries", "mezzanine.twitter", #"mezzanine.accounts", #"mezzanine.mobile",
TEMPLATE_CONTEXT_PROCESSORS = ( "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", "django.core.context_processors.debug", "django.core.context_processors.i18n", "django.core.context_processors.static", "django.core.context_processors.media", "django.core.context_processors.request", "django.core.context_processors.tz", "mezzanine.conf.context_processors.settings", "mezzanine.pages.context_processors.page", )
with TEMPLATE_CONTEXT_PROCESSORS for mezzaine:
"mezzanine.conf.context_processors.settings", "mezzanine.pages.context_processors.page",
MIDDLEWARE_CLASSES = ( "mezzanine.core.middleware.UpdateCacheMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.locale.LocaleMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "mezzanine.core.request.CurrentRequestMiddleware", "mezzanine.core.middleware.RedirectFallbackMiddleware", "mezzanine.core.middleware.TemplateForDeviceMiddleware", "mezzanine.core.middleware.TemplateForHostMiddleware", "mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware", "mezzanine.core.middleware.SitePermissionMiddleware", # Uncomment the following if using any of the SSL settings: # "mezzanine.core.middleware.SSLRedirectMiddleware", "mezzanine.pages.middleware.PageMiddleware", "mezzanine.core.middleware.FetchFromCacheMiddleware", )
with MIDDLEWARE_CLASSES for mezzanine:
"mezzanine.core.request.CurrentRequestMiddleware", "mezzanine.core.middleware.RedirectFallbackMiddleware", "mezzanine.core.middleware.TemplateForDeviceMiddleware", "mezzanine.core.middleware.TemplateForHostMiddleware", "mezzanine.core.middleware.AdminLoginInterfaceSelectorMiddleware", "mezzanine.core.middleware.SitePermissionMiddleware", # Uncomment the following if using any of the SSL settings: # "mezzanine.core.middleware.SSLRedirectMiddleware", "mezzanine.pages.middleware.PageMiddleware", "mezzanine.core.middleware.FetchFromCacheMiddleware",
PROJ_NAME/urls.py
urlpatterns = i18n_patterns("", # Change the admin prefix here to use an alternate URL for the # admin interface, which would be marginally more secure. ("^admin/", include(admin.site.urls)), ) urlpatterns += patterns('', # We don't want to presume how your homepage works, so here are a # few patterns you can use to set it up. # HOMEPAGE AS STATIC TEMPLATE # --------------------------- # This pattern simply loads the index.html template. It isn't # commented out like the others, so it's the default. You only need # one homepage pattern, so if you use a different one, comment this # one out. url("^$", direct_to_template, {"template": "index.html"}, name="home"), # HOMEPAGE AS AN EDITABLE PAGE IN THE PAGE TREE # --------------------------------------------- # This pattern gives us a normal ``Page`` object, so that your # homepage can be managed via the page tree in the admin. If you # use this pattern, you'll need to create a page in the page tree, # and specify its URL (in the Meta Data section) as "/", which # is the value used below in the ``{"slug": "/"}`` part. # Also note that the normal rule of adding a custom # template per page with the template name using the page's slug # doesn't apply here, since we can't have a template called # "/.html" - so for this case, the template "pages/index.html" # should be used if you want to customize the homepage's template. # url("^$", "mezzanine.pages.views.page", {"slug": "/"}, name="home"), # HOMEPAGE FOR A BLOG-ONLY SITE # ----------------------------- # This pattern points the homepage to the blog post listing page, # and is useful for sites that are primarily blogs. If you use this # pattern, you'll also need to set BLOG_SLUG = "" in your # ``settings.py`` module, and delete the blog page object from the # page tree in the admin if it was installed. # url("^$", "mezzanine.blog.views.blog_post_list", name="home"), # MEZZANINE'S URLS # ---------------- # ADD YOUR OWN URLPATTERNS *ABOVE* THE LINE BELOW. # ``mezzanine.urls`` INCLUDES A *CATCH ALL* PATTERN # FOR PAGES, SO URLPATTERNS ADDED BELOW ``mezzanine.urls`` # WILL NEVER BE MATCHED! # If you'd like more granular control over the patterns in # ``mezzanine.urls``, go right ahead and take the parts you want # from it, and use them directly below instead of using # ``mezzanine.urls``. ("^", include("mezzanine.urls")), # MOUNTING MEZZANINE UNDER A PREFIX # --------------------------------- # You can also mount all of Mezzanine's urlpatterns under a # URL prefix if desired. When doing this, you need to define the # ``SITE_PREFIX`` setting, which will contain the prefix. Eg: # SITE_PREFIX = "my/site/prefix" # For convenience, and to avoid repeating the prefix, use the # commented out pattern below (commenting out the one above of course) # which will make use of the ``SITE_PREFIX`` setting. Make sure to # add the import ``from django.conf import settings`` to the top # of this file as well. # Note that for any of the various homepage patterns above, you'll # need to use the ``SITE_PREFIX`` setting as well. # ("^%s/" % settings.SITE_PREFIX, include("mezzanine.urls")) ) # Adds ``STATIC_URL`` to the context of error pages, so that error # pages can use JS, CSS and images. handler404 = "mezzanine.core.views.page_not_found" handler500 = "mezzanine.core.views.server_error"
And below are config route and view of module mezzanine.accounts:
if _old_accounts_enabled or "mezzanine.accounts" in settings.INSTALLED_APPS: # We don't define a URL prefix here such as /account/ since we want # to honour the LOGIN_* settings, which Django has prefixed with # /account/ by default. So those settings are used in accounts.urls urlpatterns += patterns("", ("^", include("mezzanine.accounts.urls")), )
from __future__ import unicode_literals from django.conf.urls import patterns, url from mezzanine.conf import settings ACCOUNT_URL = getattr(settings, "ACCOUNT_URL", "/accounts/") OLD_ACCOUNT_URL = "/account/" SIGNUP_URL = getattr(settings, "SIGNUP_URL", "/%s/signup/" % ACCOUNT_URL.strip("/")) SIGNUP_VERIFY_URL = getattr(settings, "SIGNUP_VERIFY_URL", "/%s/verify/" % ACCOUNT_URL.strip("/")) LOGIN_URL = settings.LOGIN_URL LOGOUT_URL = settings.LOGOUT_URL PROFILE_URL = getattr(settings, "PROFILE_URL", "/users/") PROFILE_UPDATE_URL = getattr(settings, "PROFILE_UPDATE_URL", "/%s/update/" % ACCOUNT_URL.strip("/")) PASSWORD_RESET_URL = getattr(settings, "PASSWORD_RESET_URL", "/%s/password/reset/" % ACCOUNT_URL.strip("/")) PASSWORD_RESET_VERIFY_URL = getattr(settings, "PASSWORD_RESET_VERIFY_URL", "/%s/password/verify/" % ACCOUNT_URL.strip("/")) _verify_pattern = "/(?P<uidb36>[-\w]+)/(?P<token>[-\w]+)" _slash = "/" if settings.APPEND_SLASH else "" urlpatterns = patterns("mezzanine.accounts.views", url("^%s%s$" % (LOGIN_URL.strip("/"), _slash), "login", name="login"), url("^%s%s$" % (LOGOUT_URL.strip("/"), _slash), "logout", name="logout"), url("^%s%s$" % (SIGNUP_URL.strip("/"), _slash), "signup", name="signup"), url("^%s%s%s$" % (SIGNUP_VERIFY_URL.strip("/"), _verify_pattern, _slash), "signup_verify", name="signup_verify"), url("^%s%s$" % (PROFILE_UPDATE_URL.strip("/"), _slash), "profile_update", name="profile_update"), url("^%s%s$" % (PASSWORD_RESET_URL.strip("/"), _slash), "password_reset", name="mezzanine_password_reset"), url("^%s%s%s$" % (PASSWORD_RESET_VERIFY_URL.strip("/"), _verify_pattern, _slash), "password_reset_verify", name="password_reset_verify"), url("^%s%s$" % (ACCOUNT_URL.strip("/"), _slash), "account_redirect", name="account_redirect"), url("^%s(/(?P<url_suffix>.*))?%s$" % (OLD_ACCOUNT_URL.strip("/"), _slash), "old_account_redirect", name="old_account_redirect"), ) if settings.ACCOUNTS_PROFILE_VIEWS_ENABLED: urlpatterns += patterns("mezzanine.accounts.views", url("^%s%s$" % (PROFILE_URL.strip("/"), _slash), "profile_redirect", name="profile_redirect"), url("^%s/(?P<username>.*)%s$" % (PROFILE_URL.strip("/"), _slash), "profile", name="profile"), )
def login(request, template="accounts/account_login.html"): """ Login form. """ form = LoginForm(request.POST or None) if request.method == "POST" and form.is_valid(): authenticated_user = form.save() info(request, _("Successfully logged in")) auth_login(request, authenticated_user) return login_redirect(request) context = {"form": form, "title": _("Log in")} return render(request, template, context) def logout(request): """ Log the user out. """ auth_logout(request) info(request, _("Successfully logged out")) return redirect(next_url(request) or get_script_prefix())
TEMPLATE_DIRS = (os.path.join(PROJECT_ROOT, "templates"),) TEMPLATE_LOADERS = ( "django.template.loaders.filesystem.Loader", "django.template.loaders.app_directories.Loader", )
⇒ we will override the original template of mezzanine by create new template on directory templates
django shop: https://github.com/divio/django-shop
haystack search: https://github.com/django-haystack/django-haystack
django có sẵn những tính năng mặc định sẽ được cài bên dưới:
'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles',
Bên dưới ta sẽ liệt kê một số tính năng mà opensource có sẵn và cách hỗ trợ những tính năng này trong django:
Kinh nghiệm sử dụng lại những module đã được phát triển bởi cộng đồng django: django là framework được thiết kế với chuẩn DRY, vì thế những module mà cộng đồng phát triển có thể sử dụng lại và được tích hợp vào ứng dụng của mình một cách dễ dàng. Thông thường khi cộng đồng phát triển module như thế, ngoài việc đưa module đó vào INSTALLED_APPS cho việc load module và install những table cần thiết liên quan đến module, cần cung cấp một đối tượng dạng Manager, hoặc file cấu hình của module để giúp module đó tương tác với module khác
Admin themes:
Front-End themes: