Archivio

Posts Tagged ‘django’

djangofantalega: model Season

14 Novembre 2016 Commenti chiusi

2 – djangofantalega: model Season

Creare ‘Season’ (stagione) il primo model dell’applicazione e
madre di tutte le tabelle.

season

L’unico campo nella tabella ‘Season’, sarà ‘name’.
Creare il file fantalega/validators.py con all’interno il
validator da utilizzare:

from django.core.exceptions import ValidationError
import re


def validate_season_name(name):
    pattern = '^\d{4}-\d{4}$'
    if not re.compile(pattern).match(name):
        raise ValidationError('name %s is not correct: yyyy-yyyy is mandatory'\
            % name, params={'name': name},)

Nel file fantalega/models.py creare ora la classe Season.

from django.db import models
from fantalega.validators import validate_season_name


class Season(models.Model):
    name = models.CharField(max_length=9, validators=[validate_season_name])

    def __unicode__(self):
        return self.name

Attenzione:
questo validator vale in fase di inserimento dati da interfaccia di Admin.
Qualora i dati fossero inseriti da shell, non sarebbe attivo

Aggiornare il database con la prima migrazione, inserendo le prima tabella:

(venv) >python manage.py makemigrations fantalega
Migrations for 'fantalega':
  fantalega\migrations\0001_initial.py:
    - Create model Season

confermare con:

(venv) >python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, fantalega, sessions
Running migrations:
  Applying fantalega.0001_initial... OK

Creare la prima Season da shell:

(venv) >python manage.py shell
>>> from fantalega.models import Season
>>> Season.objects.create(name='2016-2017')
...
>>> exit()

Registrare l’amministratore del sito.

python manage.py createsuperuser
Username (leave blank to use 'xxxxxxxxxx'):
Email address: [email protected]
Password:
Password (again):
Superuser created successfully.

Attivare nel pannello di admin, il model Season appena creato

file fantalega/admin.py

# noinspection PyUnresolvedReferences
from django.contrib import admin
from .models import Season


# Register your models here.
admin.site.register(Season)

lanciare il server con il comando:

python manage.py runserver

ed andare alla pagina http://127.0.0.1:8000/admin/
dove verremo reindirizzati alla sezione di login.
Immettere le credenziali appena registrate.

admin_season_ok

Qualora si volessero aggiungere nuove Season dall’Admin,
entrerebbe in gioco il validator precedentemente creato.
Es. se si creasse una Season con nome ‘season 1’, il validator
solleverebbe un’eccezione:

season_validate_error

altrimenti, rispettando il pattern della regex, il tutto andrebbe a buon fine:

admin_season_ok

Chiaramente non tutto si svolgerà all’interno dell’interfaccia di admin,
pertanto saranno create:

    una url che visualizzerà la lista delle Season, richiamando la vista (view) di competenza;
    la view, richiamata dalla url precedente, che salverà i dati su database o li
    richiederà per poi fornirli alla template;
    la template che visualizzerà i dati

Creare la url nel file fantalega/urls.py:

# noinspection PyUnresolvedReferences
from django.conf.urls import url
# noinspection PyUnresolvedReferences
from django.contrib import admin
from . import views


urlpatterns = [
    url(r'^$', views.index, name='index'),
    # season urls
    url(r'^seasons/$', views.seasons, name='seasons'),
]

Creare la view nel file fantalega/views.py

# noinspection PyUnresolvedReferences
from django.shortcuts import render, redirect, get_object_or_404
from .models import Season
# noinspection PyUnresolvedReferences
from django.contrib import messages


def index(request):
    return render(request, 'fantalega/index.html')


def seasons(request):
    context = {'seasons': Season.objects.order_by('-name')}
    return render(request, 'fantalega/seasons.html', context)

E ora le templates.
dentro la directory fantalega, creare una sottodirectory “templates” ed al suo interno,
un’altra sottodirectory “fantalega”. ALl’interno di quest’ultima creare un file
base.html:

fantalega\templates\fantalega\base.html

{% load staticfiles %}
{# Load the tag library #}
{% load bootstrap3 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{% load app_filters %}

{% block head %}
{% endblock %}

{% block navbar %}
  <div class="navbar navbar-inverse" role="navigation">
    <div class="container">
    {% if user.is_anonymous %}
      <div class="navbar-header">
        <a class="navbar-brand">
            Bancaldo
            <font color="green">Fan</font><font color="white">tal</font><font color="red">ega</font>
            please login</a></div>
    {% else %}
      {% if user.is_staff %}
        <div class="navbar-header">
          <a class="navbar-brand" href="{% url 'admin:index' %}">
              <font color="red">Admin</font></a></div>
      {% endif %}
      <div class="navbar-header">
        <a class="navbar-brand" href="{% url 'seasons' %}">Seasons</a></div>
    {% endif %}

      <div class="navbar-collapse collapse">
        <ul class="nav navbar-nav navbar-right">
        {% if not user.is_anonymous %}
          <li><a class="navbar-brand"
             href="{% url 'logout' %}">
          <font color="orange">logout</font></a></li>
        {% endif %}
        </ul>
      </div>
    </div>
  </div>
{% endblock %}

<html>
    <head>
      <title>{% block title %}Django Fantalega{% endblock %}</title>
    </head>
    <body>
      {% if messages %}
        <ul class="list-unstyled messages">
        {% for message in messages %}
          {% get_bootstrap_alert_msg_css_name message.tags as alert_tag %}
          <li class="alert alert-{{ alert_tag }}">{{ message }}</li>
        {% endfor %}
        </ul>
      {% endif %}

      <div class="content container">
        <div class="row">
          <div class="col-md-8">
            {% block content %}
            {% endblock %}
          </div>
        </div>
      </div>
    </body>
</html>

Questa è la template base dalla quale erediteranno tutte le altre.

Creare ora la template per l’index (fantalega\templates\fantalega\index.html):

{% extends "fantalega/base.html" %}
{% block content %}
  <h1><font color="green">Fantalega</font></h1><br>
  {% if user %}
    <b><font color="blue">{{ user.username }}, </font>
       <font color="orange">you are welcome!</font>
    </b>
  {% endif %}
{% endblock %}

Poi creare il file fantalega\templates\fantalega\seasons.html

{% extends 'fantalega/base.html' %}

{% block content %}
        <h1><font color="green">List of SEASONS</font></h1>
    {% if seasons %}
    <ul>
      {% for season in seasons %}
      <li>{{ season.name }}</a></li>
      {% endfor %}
    </ul>
    {% else %}
      <font color="red"><b>No season found.</b></font>
    {% endif %}
{% endblock %}

Avviare il server qualora già non lo fosse e recarsi all’indirizzo:

python manage.py runserver

ed andare alla pagina http://127.0.0.1:8000/fantalega/seasons

Cosa è successo?
nel file urls.py l’indirizzo suddetto viene matchato dalla regex
r’^seasons/$’ (primo parametro della seconda url della lista urlpatterns), alla quale
corrisponde la view ‘seasons’ (file fantalega/views.py).
In questa views, viene creato un dizionario ‘context’ con all’interno la lista di tutte
le Season presenti nel database

context = {'seasons': Season.objects.order_by('-name')}

il dizionario viene passato alla funzione render() che lo fornisce alla template
‘fantalega/seasons.html’ sotto forma di tag ‘{{ seasons }}’.
In questo caso, il tag seasons non è diretto, ma viene raggiunto tramite ciclo for
‘{% for season in seasons %}’…

Nota:
Come si nota, nella template ‘base.html’, dalla quale ereditiamo, nelle sezioni
navbar, tramite il tag {{ url }} si richiama il nome ‘seasons’, che è il terzo fondamentale
paramtero usato nella costruzione delle urls.

      <div class="navbar-header">
        <a class="navbar-brand" href="{% url 'seasons' %}">Seasons</a></div>

le seasons sono quindi raggiungibili anche dalla barra superiore (navbar che viene
ereditata da base.html), inoltre se l’utente con il quale ci si logga, è superuser (is_staff),
può amministrare cliccando su Admin.

seasons

Salvare gli avanzamenti su github:

git add --all
git commit -m "Season added"
git push -u origin master

articoli precedenti
0 – indice
1 – Virtualenv e Git

articoli successivi
3 – Admin: Login e Logout
4 – Models: League
5 – Models: Team
6 – Models: Match
7 – Models: Player
8 – Asta
9 – Models: Lineup
10 – Models: Trade
11 – Asta di riparazione
12 – Classifica

Categorie:Django Tag:

djangofantalega: virtualenv e git

14 Novembre 2016 Commenti chiusi

1- Djangofantalega: virtualenv e git

Settare virtaulenv all’interno della directory che ospiterà il progetto:

virtualenv venv

abilitare l’ambiente virtuale:
windows

venv\Scripts\activate

linux

source venv/bin/activate

installare l’ultima versione di django (attualmente la 1.10)

pip install django

installare anche bootstrap (per rendere meno spartane le templates):

pip install django-bootstrap3

creare il progetto con django

django-admin startproject djangosite

spostarsi all’interno del progetto appena creato:

cd djangosite

creare la prima applicazione base, in questo caso ‘fantalega’:

python manage.py startapp fantalega

configurare il file djangosite\settings.py aggiungendo nelle
applicazioni installate, ‘fantalega’ (dovrebbe essere aggiunta in automatico)
e ‘bootstrap3’:

INSTALLED_APPS = [
    'fantalega.apps.FantalegaConfig',  # dovrebbe essere di default
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'bootstrap3'  # aggiungere questa riga
]
...
LANGUAGE_CODE = 'it-IT'
...

Nota:
FantalegaConfig è una classe che eredita da AppConfig,
presente all’interno del file fantalega\apps.py, con
attributo name=’fantalega’

Creare il database nudo e crudo:

python manage.py migrate
(venv) >python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  ...
  Applying sessions.0001_initial... OK

Prima di creare i models del progetto, utilizzare git per
tenere traccia di tutte le modifiche.
Inizializzare il repository del progetto, senza cambiare directory

git init

settare i parametri utente ed email:

git config --global user.name "bancaldo"
git config --global user.email "[email protected]"

siccome non si vuole tenere traccia di alcuni file, quali il database, o il
virtual environment, compiliamo il file ‘.gitignore’, con l’elenco dei file
che non sono desiderati:

*.pyc
__pycache__
venv
db.sqlite3
/static

controllare cosa dice git sulla situazione di partenza

git status
On branch master

Initial commit

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        .gitignore
        djangosite/
        fantalega/
        manage.py

nothing added to commit but untracked files present (use "git add" to track)

come si nota, non appaiono nè il database (db.sqlite3), nè la directory venv.
A questo punto aggiungere tutti i file al nostro repo:

git add --all

è buona abitutine allegare sempre un messaggio al commit per le future ricognizioni.

git commit -m "primo commit applicazione fantalega

creare su github.com un nuovo repo e
terminata la creazione, collegare il tutto:

git remote add origin https://github.com/bancaldo/djangofantalega.git

ora “buttare” il contenuto del nostro repo LOCALE, su github:

git push -u origin master

chiaramente fornendo le credenziali di accesso a github.
Nel caso ci fosse un proxy, potrebbe verificarsi questo errore:

Failed to connect to github.com port 443: Connection refused

Configurare git per gestire il proxy:

git config --global http.proxy https://<nume-user>:<password-user>@<nome-proxy>:<porta>

qualora le impostazioni del proxy nel browser, fossero settate in automatico e quindi non visibili,
utilizzare questo comando:

reg query "HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Internet Settings" | find /i "proxyserver"

rilanciare il comando:

git push -u origin master

Username for 'https://github.com': .....
Password for 'https://[email protected]':
Counting objects: 16, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (13/13), done.
Writing objects: 100% (16/16), 3.41 KiB | 0 bytes/s, done.
Total 16 (delta 0), reused 0 (delta 0)
To https://github.com/bancaldo/djangofantalega.git
 * [new branch]      master -> master
Branch master set up to track remote branch master from origin.

articoli precedenti
0 – indice

articoli successivi
2 – Models: Season
3 – Admin: Login e Logout
4 – Models: League
5 – Models: Team
6 – Models: Match
7 – Models: Player
8 – Asta
9 – Models: Lineup
10 – Models: Trade
11 – Asta di riparazione
12 – Classifica

Categorie:Django Tag: , ,

Django: bootstrap3 template messages

9 Novembre 2016 Commenti chiusi

Per la gestione dei messaggi con django e bootstrap3,
aggiungere al file myapp/templatetags/app_filters.py

# noinspection PyUnresolvedReferences
from django import template


register = template.Library()

@register.assignment_tag
def get_bootstrap_alert_msg_css_name(tags):
    return 'danger' if tags == 'error' else tags

e nella template myapp/templates/base.html dalla quale ereditano tutte le altre:

{% load staticfiles %}
{# Load the tag library #}
{% load bootstrap3 %}
{# Load CSS and JavaScript #}
{% bootstrap_css %}
{% bootstrap_javascript %}
{% load app_filters %}
...
<html>
    <head>
      <title>{% block title %}Myapp{% endblock %}</title>
    </head>
    <body>
      {% if messages %}
        <ul class="list-unstyled messages">
        {% for message in messages %}
          {% get_bootstrap_alert_msg_css_name message.tags as alert_tag %}
          <li class="alert alert-{{ alert_tag }}">{{ message }}</li>
        {% endfor %}
        </ul>
      {% endif %}

      <div class="content container">
        <div class="row">
          <div class="col-md-8">
            {% block content %}
            {% endblock %}
          </div>
        </div>
        <br>
      </div>
    </body>
</html>

All’interno di views.py:

from django.contrib import messages

def a_view(request):
    ...
    messages.warning(request, "warning message")
    messages.info(request, "info message")
    messages.error(request, "error message")
    messages.success(request, "success message")
    ...
Categorie:Django Tag:

Django: template custom_filter

9 Novembre 2016 Commenti chiusi

Per elaborare una variabile all’interno di una template di django,
è possibile utilizzare custom_filter.

Per prima cosa creare all’interno della directory myapp,
una sottodirectory ‘templatetags’, con all’interno un file vuoto __init__.py
e un file app_filters.py.

All’interno del file app_filters.py:

# noinspection PyUnresolvedReferences
from django import template
from django.utils.safestring import mark_safe


register = template.Library()


@register.filter(name='pts_filter')
def pts_filter(value):
    if value:
        if float(value) <= 60:
            color = 'e60000'
        elif 60 < float(value) <= 72:
            color = 'cc66ff'
        else:
            color = '009933'
        new_string = '<b><font color="#%s">%s</font></b>' % (color, value)
        return mark_safe(new_string)
    else:
        return value

Nella template i filters vanno caricati all’inizio con la voce:

{% load app_filters %}

mentre il filtro verrà chiamato con la sintassi ‘value|filter:

{{ value|pts_filter }}

il valore ‘value’ viene passato come argomento alla funzione pts_filter()
che ritorna lo stesso valore dopo averlo modificato.
E’ assolutamente necessario ritornare il valore con mark_safe.

Qualora dovessimo anche passare un argomento al filter si userà la sintassi
tag|filter:arg ad esempio:

<b>player avg</b>: {{ player|get_avg:player.code}}

dove il filter sarà:

@register.filter(name='get_avg')
def get_avg(player, code):
    obj_player = Player.objects.filter(name=player, code=code).first()
    values = [e.value for e in Evaluation.objects.filter(player=obj_player).all()
              if e.value > 0.0 ]
    return float(sum(values))/len(values)

Le template di django non sono completamente duttili ma è possibile creare dei tag specifici
che compiano operazioni e ritornino determinate cose.
Ad esempio filtrare queryset secondo determinati argomenti:

@register.assignment_tag
def filter_iterable(iterable, value):
    return iterable.filter(arg=value)

nella template sarà richiamato così:

{% filter_iterable iterable day as f_iterable %}
  {% for item in f_iterable %}
    {{ item.arg1 }}
    {{ item.arg2 }}
Categorie:Django Tag:

Django: Model.field custom validator

8 Novembre 2016 Commenti chiusi

Ho un model Season, con un field ‘name’.
Voglio che siano accettati solo nomi con il formato
‘yyyy-yyyy’ es. ‘2016-2017’.
Per essere sicuro che, in sede di creazione da interfaccia
di Admin, venga rispettato questo criterio, posso creare un
validator.

Nella stessa directory dove risiedono i models, creo un file
validators.py con all’interno il mio custom validator.

from django.core.exceptions import ValidationError
import re


def validate_season_name(name):
    pattern = '^\d{4}-\d{4}$'
    if not re.compile(pattern).match(name):
        raise ValidationError('name %s is not correct: yyyy-yyyy is mandatory'\
            % name, params={'name': name},)

Nel file models.py userò il validator direttamente
nella definizione del field ‘name’:

# noinspection PyUnresolvedReferences
from django.db import models
from myapp.validators import validate_season_name


class Season(models.Model):
    name = models.CharField(max_length=9, validators=[validate_season_name])

    def __unicode__(self):
        return self.name

Ovviamente, essendo l’argomento validators una lista, posso utilizzare più validators.

Quando andrò a creare la Season ed inserirò
un nome non desiderat, verrà sollevata l’eccezione.
season_validate_error

Altrimenti tutto sarà ok.
admin_season_ok

Categorie:Django Tag:

Django: unknown command validate

1 Giugno 2016 Commenti chiusi

per validare i models prima si utilizzava il comando:

python manage.py validate

nella versione attuale di django (1.9.x) questo solleva un errore:

(venv) C:\...\bancaldo\mysite>python manage.py validate
Unknown command: 'validate'
Type 'manage.py help' for usage.

il comando da utilizzare è “check”:

(venv) C:\...\bancaldo\mysite>python manage.py check
System check identified no issues (0 silenced).
Categorie:Django, python Tag: ,

Django: too many values to unpack

3 Aprile 2013 Commenti chiusi

Mi è capitato dopo un’aggiornamento di Django, di tentare
di entrare nella sezione di Admin di una mia app, senza successo.
L’errore era sempre il medesimo:

ValueError at /admin/

too many values to unpack

Request Method: 	POST
Request URL: 	http://127.0.0.1:8000/admin/
Django Version: 	1.3
Exception Type: 	ValueError
Exception Value: 	

too many values to unpack
...

controllando il traceback si risale alla causa dell’errore:

algo, salt, hsh = enc_password.split('$')

In pratica la gestione della password è cambiata tra le diverse
versioni di django, per cui una password settata con una versione
di django, è mal digerita nei tentativi di accesso successivi, con
versioni di django differenti.

per sistemare la password, da terminale è possibile utilizzare il
comando:

python manage.py changepassword <username>

Rilanciato il server l’accesso alla sezione di admin è tornata
a funzionare correttamente.

Nota:

Controllando la tabella “auth_user” abbiamo la password criptata,
così composta:

sha1$d1692$11ea66b009f66672b7bdfe8ef3a2df1cc8acc37d

come si nota appaiono due simboli ‘$’, grazie ai quali la riga di
codice

algo, salt, hsh = enc_password.split('$')

splitta la stringa sulle tre variabili algo, salt e hsh.
Qualora la password non avesse questa struttura si solleverebbe
l’eccezione che non consente l’accesso alla sezione di admin.

Categorie:Django Tag:

Django 1.2: tiny_mce 3.3.9.2

15 Novembre 2010 Commenti chiusi

Ho scaricato Tiny_mce versione 3.3.9.2.
L’ho scompattato in una directory temporanea.

Nel mio progetto libreria, ho creato una sottodirectory \content.
E dentro content ho creato un’altra sottodirectory \js.
Dalla directory temporanea (contente tiny_mce), entro nella sottodir
\tinymce_3_3_9_2\tinymce\jscripts e copio la sottodir tiny_mce,
dentro alla precedentemente creata \content\js.

Sempre dentro a \content\js, oltre ad avere ora la sottodir
tiny_mce, creo un file textareas.js dnetro al quale scrivo il
seguente codice:

tinyMCE.init({
	mode: "textareas",
	theme: "advanced",
	width : "300",
	height : "200",

});

Per prima cosa verifico che i file .js dei quali ho bisogno,
vengano visti correttamente.
Controllo che nel file settings.py ci siano le costanti
dei percorsi settate correttamente:

SITE_ROOT = os.path.dirname(os.path.realpath(__file__)).replace("\\", "/")
MEDIA_ROOT = os.path.join(SITE_ROOT, 'content/').replace("\\", "/")
MEDIA_URL = '/media/'
ADMIN_MEDIA_PREFIX = '/admin-media/' 

Avvio il server con

python manage.py runserver

e vado all’indirizzo:

http://127.0.0.1:8000/media/js/textareas.js

controllo che venga caricato anche tiny_mce.js, all’indirizzo:

http://127.0.0.1:8000/media/js/tiny_mce/tiny_mce.js


Sempre con riferimento all’esempio wikisearch del libro di Marco Beri,

nel file libreria\views_wiki.py aggiungo la meta class Media con
i riferimenti ai path dei file .js:

class WikisearchForm(forms.Form):
    class Media:
	from settings import MEDIA_URL
        js = ( MEDIA_URL + "/js/tiny_mce/tiny_mce.js",
               MEDIA_URL + "/js/textareas.js",)
    ...

mentre nel template base.html aggiungo un tag extrahead:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en" >
<head>
	<title>{% block title %}Hello world!{% endblock %}</title>

	{% block extrahead %}{% endblock %}

e nell’estensione wikisearch.html:

{% extends 'base.html'%}

{% block title%}Ricerca Wikipedia{% endblock %}

{% block extrahead %}{{ block.super }}

	<script type="text/javascript" src="/media/js/tiny_mce/tiny_mce.js"></script>
	<script type="text/javascript" src="/media/js/textareas.js"></script>
{% endblock %}
...

Come ultima cosa, aggiungiamo nell’urlCONF, l’ultimo tassello:

(r'^libri/ricerca/$', 'libreria.views_wiki.ricerca'),

Il tutto sembra funzionare, caricando l’url:

http://127.0.0.1:8000/libri/ricerca/

Categorie:Django Tag: