-- What is the Web?
-- How does the Web work?
On login, a token of user information is saved (most often on the client side, in special files called cookies)
so that each request the user makes carries the means fo the server to recognize the user and provide a custom interface by showing the name,
keeping eh basket populated,and so on.
-- The Django web framework
A web framework is a set of tools(libraries, functions, classes, and so on) that can use to code a website.
Django design philosophy
DRY: Don't repeat yourself.
Loose coupling
Less code
Consistency
The Model Layer
A model is a class that represents a data structure.
This layer deals with defining the data structures you need to handle in your website and gives you the means to save and load them from and to the database by simply accessing the models, which are Python objects.
The View Layer
the view is the mechanism through which we can fulfill a request. Its result, the response object, can assume several different forms: a JSON payload, text, an HTML page, and so on. When you code a website, your responses usually consist of HTML or JSON.
THE Template Layer
The layout of the page is defined by a template, which is written in a mixture of HTML and Django template language.
The Django URL dispatcher
REGULAR EXPRESSIONS
A regular expression is a sequence of characters that defines a search pattern with which we can carry out operations such as pattern and string matching, find/replace, and so on.
-- A regex website
CSS (Cascading Style Sheets) are files in which we specify how the various elements on an HTML page look. You can set all sorts of properties such as shape, size, color, margins, borders, fonts, and so on.
Setting up Django
$ pip install django
import django
django.VERSION
Starting the project
$ django-admin startproject regex
$ tree -A regex # from the ch10 folder
$ python manage.py startapp entries
INSTALLED_APPS = (
... django apps ...
'entries',
)
LANGUAGE_CODE = 'en-gb'
TIME_ZONE = 'Europe/London'
$ python manage.py migrate
Creating users
$ python manage.py createsuperuser
$ python manage.py runserver
Adding the Entry model
entries/models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
class Entry(models.Model):
user = models.ForeignKey(User)
pattern = models.CharField(max_length=255)
test_string = models.CharField(max_length=255)
date_added = models.DateTimeField(default=timezone.now)
class Meta:
verbose_name_plural = 'entries'
$ python manage.py makemigrations entries
$ python manage.py migrate
Customizing the admin panel
entries/admin.py
from django.contrib import admin
from .models import Entry
@admin.register(Entry)
class EntryAdmin(admin.ModelAdmin):
fieldsets = [
('Regular Expression',
{'fields': ['pattern', 'test_string']}),
('Other Information',
{'fields': ['user', 'date_added']}), ]
list_display = ('pattern', 'test_string', 'user')
list_filter = ['user']
search_fields = ['test_string']
Creating the form
entries/forms.py
from django.forms import ModelForm
from .models import Entry
class EntryForm(ModelForm):
class Meta:
model = Entry
fields = ['pattern', 'test_string']
Writing the views
entries/views.py
import re
from django.contrib.auth.decorators import login_required
from django.contrib.messages.views import SuccessMessageMixin
from django.core.urlresolvers import reverse_lazy
from django.utils.decorators import method_decorator
from django.views.generic import FormView, TemplateView
from .forms import EntryForm
from .models import Entry
class HomeView(TemplateView):
template_name = 'entries/home.html'
@method_decorator(
login_required(login_url=reverse_lazy('login')))
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
return self.render_to_response(context)
class EntryListView(TemplateView):
template_name = 'entries/list.html'
@method_decorator(
login_required(login_url=reverse_lazy('login')))
def get(self, request, *args, **kwargs):
context = self.get_context_data(**kwargs)
entries = Entry.objects.filter(
user=request.user).order_by('-date_added')
matches = (self._parse_entry(entry) for entry in entries)
context['entries'] = list(zip(entries, matches))
return self.render_to_response(context)
def _parse_entry(self, entry):
match = re.search(entry.pattern, entry.test_string)
if match is not None:
return (
match.group(),
match.groups() or None,
match.groupdict() or None
)
return None
class EntryFormView(SuccessMessageMixin, FormView):
template_name = 'entries/insert.html'
form_class = EntryForm
success_url = reverse_lazy('insert')
success_message = "Entry was created successfully"
@method_decorator(
login_required(login_url=reverse_lazy('login')))
def get(self, request, *args, **kwargs):
return super(EntryFormView, self).get(
request, *args, **kwargs)
@method_decorator(
login_required(login_url=reverse_lazy('login')))
def post(self, request, *args, **kwargs):
return super(EntryFormView, self).post(
request, *args, **kwargs)
def form_valid(self, form):
self._save_with_user(form)
return super(EntryFormView, self).form_valid(form)
def _save_with_user(self, form):
self.object = form.save(commit=False)
self.object.user = self.request.user
self.object.save()
The home view
THE ENTRY LIST VIEW
The form view
Tying up URLs and views
regex/urls.py
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.core.urlresolvers import reverse_lazy
from entries.views import HomeView, EntryListView, EntryFormView
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^entries/$', EntryListView.as_view(), name='entries'),
url(r'^entries/insert$', EntryFormView.as_view(), name='insert'),
url(r'^login/$', auth_views.login, kwargs={'template_name': 'admin/login.html'}, name='login'),
url(r'^logout/$', auth_views.logout, kwargs={'next_page': reverse_lazy('home')}, name='logout'),
url(r'^$', HomeView.as_view(), name='home'),
]
Writing the templates
entries/templates/entries/base.html
{% load static from staticfiles %}
<!DOCTYPE html>
<html lang="en">
<head>
{% block meta %}
<meta charset="utf-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
{% endblock meta %}
{% block styles %}
<link href="{% static "entries/css/main.css" %}"
rel="stylesheet">
{% endblock styles %}
<title> {% block title %}Title{% endblock title %} </title>
</head>
<body>
<div id="page-content">
{% block page-content %}
{% endblock page-content %}
</div>
<div id="footer">
{% block footer %}
{% endblock footer %}
</div>
</body>
</html>
entries/templates/entries/footer.html
<div class="footer">
Go back <a href="{% url "home" %}">home</a>.
</div>
entries/templates/entries/home.html
{% extends "entries/base.html" %}
{% block title%}Welcome to the Entry website.{% endblock title %}
{% block page-content %}
<h1>Welcome {{ user.first_name }}!</h1>
<div class="home-option">To see the list of your entries
please click <a href="{% url "entries" %}">here.</a>
</div> <div class="home-option">To insert a new entry please click
<a href="{% url "insert" %}">here.</a>
</div> <div class="home-option">To login as another user please click
<a href="{% url "logout" %}">here.</a>
</div>
<div class="home-option">To go to the admin panel
please click <a href="{% url "admin:index" %}">here.</a>
</div>{% endblock page-content %}
entries/templates/entries/insert.html
{% extends "entries/base.html" %}
{% block title%}Insert a new Entry{% endblock title %}
{% block page-content %}
{% if messages %}
{% for message in messages %}
<p class="{{ message.tags }}">{{ message }}</p>
{% endfor %}
{% endif %}
<h1>Insert a new Entry</h1>
<form action="{% url "insert" %}" method="post">
{% csrf_token %}{{ form.as_p }}
<input type="submit" value="Insert">
</form><br>
{% endblock page-content %}
{% block footer %}
<div><a href="{% url "entries" %}">See your entries.</a></div>
{% include "entries/footer.html" %}
{% endblock footer %}
entries/templates/entries/list.html
{% extends "entries/base.html" %}
{% block title%} Entries list {% endblock title %}
{% block page-content %}
{% if entries %}
<h1>Your entries ({{ entries|length }} found)</h1>
<div><a href="{% url "insert" %}">Insert new entry.</a></div>
<table class="entries-table">
<thead>
<tr><th>Entry</th><th>Matches</th></tr>
</thead>
<tbody>
{% for entry, match in entries %}
<tr class="entries-list {% cycle 'light-gray' 'white' %}">
<td>
Pattern: <code class="code">
"{{ entry.pattern }}"</code><br>
Test String: <code class="code">
"{{ entry.test_string }}"</code><br>
Added: {{ entry.date_added }}
</td>
<td>
{% if match %}
Group: {{ match.0 }}<br>
Subgroups:
{{ match.1|default_if_none:"none" }}<br>
Group Dict: {{ match.2|default_if_none:"none" }}
{% else %}
No matches found.
{% endif %}
</td>
</tr>
{% endfor %}
</tbody> </table>
{% else %}
<h1>You have no entries</h1>
<div><a href="{% url "insert" %}">Insert new entry.</a></div>
{% endif %}{% endblock page-content %}
{% block footer %}
{% include "entries/footer.html" %}
{% endblock footer %}
-- The future of web development
Writing a Flask view
$ tree -A flask # from the ch10 folder
flask/templates/main.html
<!doctype html>
<title>Hello from Flask</title>
<h1>
{% if name %}
Hello {{ name }}!
{% else %}
Hello shy person!
{% endif %}
</h1>
flask/main.py
from flask import Flask, render_template
app = Flask(__name__)
@app.route('/')
@app.route('/<name>')
def hello(name=None):
return render_template('main.html', name=name)
if __name__ == '__main__':
app.run()
$ python main.py
Building a JSON quote server in Falcon
falcon/quotes.py
quotes = [
"Thousands of candles can be lighted from a single candle, "
"and the life of the candle will not be shortened. "
"Happiness never decreases by being shared.",
...
"Peace comes from within. Do not seek it without.",
]
falcon/main.py
import json
import random
import falcon
from quotes import quotes
class QuoteResource:
def on_get(self, req, resp):
quote = {
'quote': random.choice(quotes),
'author': 'The Buddha'
}
resp.body = json.dumps(quote)
api = falcon.API()
api.add_route('/quote', QuoteResource())
$ gunicorn main:api
No comments:
Post a Comment