Skip to content
Luke Chen edited this page May 22, 2021 · 28 revisions

Installation

https://www.djangoproject.com/download/

$ pip install Django==3.1.7
$ python
Python 3.8.5 (default, Sep  4 2020, 07:30:14) 
[GCC 7.3.0] :: Anaconda, Inc. on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import django
>>> print(django.get_version())
3.1.7

Upgrade to the latest

$ python -m pip install -U Django
$ python -m django --version
3.2.3

Getting started

https://www.djangoproject.com/start/

Tutorial

https://docs.djangoproject.com/en/3.2/intro/tutorial01/

The tutorial ends with:

http://10.0.0.44:8899/admin/

http://10.0.0.44:8899/polls/

Network Config

UFW Firewall Rules

https://www.digitalocean.com/community/tutorials/how-to-set-up-a-firewall-with-ufw-on-ubuntu-18-04 https://linuxize.com/post/how-to-list-and-delete-ufw-firewall-rules/

$ sudo ufw status verbose

$ sudo ufw enable

$ sudo ufw default deny incoming

$ sudo ufw allow 8899

Go to mysmypoll/settings.py, and add to ALLOWED_HOSTS

ALLOWED_HOSTS = ['xxx.xxx.xxx.xxx', 'localhost', '127.0.0.1']

Go to mypolls/settings.py, and make sure the TIME_ZONE is set correctly

https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-TIME_ZONE

https://gist.github.com/heyalexej/8bf688fd67d7199be4a1682b3eec7568

# TIME_ZONE = 'UTC'
TIME_ZONE = 'America/New_York'

Setup

To create a site

$ pwd
/home/lchen154/workspace/django
$ django-admin startproject mypoll

To run tests

$ python -Wa manage.py test

To run server

# to listen on default port 8000
python manage.py runserver

# to listen on a specific port
python manage.py runserver 8899

# to listen on all available public IPs
python manage.py runserver 0:8899

Internally, go to visit http://127.0.0.1:8899/

Create app

Create the "polls" app

$ python manage.py startapp polls

Add the "index" view to polls/views.py

polls/views.py¶
from django.http import HttpResponse


def index(request):
    return HttpResponse("Hello, world. You're at the polls index.")

Create a URLconf in the polls directory, create a file called urls.py.

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index, name='index'),
]

And, point the URLconf at the polls.urls module, in mysite/urls.py.

from django.contrib import admin
from django.urls import include, path

urlpatterns = [
    path('polls/', include('polls.urls')),
    path('admin/', admin.site.urls),
]

Now, run http://127.0.0.1:8899/polls/

Connect to MySQL

Install MySQL

Install mysqlclient https://pypi.org/project/mysqlclient/

sudo apt-get install python3-dev default-libmysqlclient-dev build-essential
pip install mysqlclient

Grant all privileges to the user

mysql> GRANT ALL on *.* TO 'mysqluser1'@'localhost' WITH GRANT OPTION;
mysql> FLUSH PRIVILEGES;

Create DB

mysql> create database mypolldb;

Modify 'mypoll/settings.py'

DATABASES = {
    # 'default': {
    #     'ENGINE': 'django.db.backends.sqlite3',
    #     'NAME': BASE_DIR / 'db.sqlite3',
    # }
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'mypolldb',
        'USER': 'mysqluser1',
        'PASSWORD': 'testtest1',
        'HOST': '127.0.0.1',
        'PORT': '3306',
    }
}

Install Apps

$ python manage.py migrate

In MySQL, you'll see

mysql> show tables;
+----------------------------+
| Tables_in_mypolldb         |
+----------------------------+
| auth_group                 |
| auth_group_permissions     |
| auth_permission            |
| auth_user                  |
| auth_user_groups           |
| auth_user_user_permissions |
| django_admin_log           |
| django_content_type        |
| django_migrations          |
| django_session             |
+----------------------------+
10 rows in set (0.01 sec)

Restart the server

$ python manage.py runserver 0:8899

Add the polls app

Add the app config to mypolls/settings.py 'polls.apps.PollsConfig' points to 'polls/apps.py' > 'PollsConfig'

INSTALLED_APPS = [
    'polls.apps.PollsConfig',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

Store changes of the 'polls' app to the models as a migration.

$ python manage.py makemigrations polls

The migration file is in polls/migrations/0001_initial.py

Use the sqlmigrate command to print out what SQL Django is going to do

$ python manage.py sqlmigrate polls 0001
--
-- Create model Question
--
CREATE TABLE `polls_question` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `question_text` varchar(200) NOT NULL, `pub_date` datetime(6) NOT NULL);
--
-- Create model Choice
--
CREATE TABLE `polls_choice` (`id` bigint AUTO_INCREMENT NOT NULL PRIMARY KEY, `choice_text` varchar(200) NOT NULL, `votes` integer NOT NULL, `question_id` bigint NOT NULL);
ALTER TABLE `polls_choice` ADD CONSTRAINT `polls_choice_question_id_c5b4b260_fk_polls_question_id` FOREIGN KEY (`question_id`) REFERENCES `polls_question` (`id`);

Use python manage.py check to check for any problems in the project without making migrations or touching the database.

Run migrate to create model tables

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, polls, sessions
Running migrations:
  Applying polls.0001_initial... OK

Guide to making model changes

The three-step guide to making model changes:

  • Change your models (in models.py)
  • Run python manage.py makemigrations to create migrations for those changes
  • Run python manage.py migrate to apply those changes to the database

Play with Django

Invoke the python shell

$ python manage.py shell

In [1]: from polls.models import Choice, Question

In [2]: Question.objects.all()
Out[2]: <QuerySet []>

In [3]: from django.utils import timezone

In [4]: q = Question(question_text="What's new?", pub_date=timezone.now())

In [5]: q.save()

In [6]: q.id
Out[6]: 1

In [7]: q.question_text
Out[7]: "What's new?"

In [8]: q.pub_date
Out[8]: datetime.datetime(2021, 5, 22, 0, 49, 43, 820343, tzinfo=<UTC>)

In [9]: q.question_text = "What's up?"

In [10]: q.save()

In [11]: Question.objects.all()
Out[11]: <QuerySet [<Question: Question object (1)>]>

In [12]: q.question_text
Out[12]: "What's up?"

Shell example 2

$ python manage.py shell

In [1]: from polls.models import Choice, Question

In [2]: Question.objects.all()
Out[2]: <QuerySet [<Question: What's up?>]>

In [3]: Question.objects.filter(id=1)
Out[3]: <QuerySet [<Question: What's up?>]>

In [5]: Question.objects.filter(question_text__startswith='What')
Out[5]: <QuerySet [<Question: What's up?>]>

In [6]: from django.utils import timezone

In [7]: current_year = timezone.now().year

In [8]: Question.objects.get(pub_date__year=current_year)
Out[8]: <Question: What's up?>

In [9]: Question.objects.get(id=2)
---------------------------------------------------------------------------
DoesNotExist                              Traceback (most recent call last)
...
DoesNotExist: Question matching query does not exist.

In [10]: Question.objects.get(pk=1)
Out[10]: <Question: What's up?>

In [11]: q = Question.objects.get(pk=1)

In [12]: q.was_published_recently()
Out[12]: True

In [13]: q = Question.objects.get(pk=1)
    ...: 

In [14]: q.choice_set.all()
Out[14]: <QuerySet []>

In [15]: q.choice_set.create(choice_text='Not much', votes=0)
Out[15]: <Choice: Not much>

In [16]: q.choice_set.create(choice_text='The sky', votes=0)
Out[16]: <Choice: The sky>

In [17]: c = q.choice_set.create(choice_text='Just hacking again', votes=0)

In [18]: c.question
Out[18]: <Question: What's up?>

In [19]: q.choice_set.all()
Out[19]: <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

In [20]: q.choice_set.count()
Out[20]: 3

In [21]: Choice.objects.filter(question__pub_date__year=current_year)
Out[21]: <QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>

In [22]: c = q.choice_set.filter(choice_text__startswith='Just hacking')

In [23]: c.delete()
Out[23]: (1, {'polls.Choice': 1})

Django Admin

Create an admin user

$ python manage.py createsuperuser
Username (leave blank to use 'lchen154'): admin
Email address: admin@mypoll.com 
Password: testtest1
Password (again): testtest1
This password is too common.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

Launch the server and go to http://127.0.0.1:8899/admin/

Created two groups and users:
"Choice Content Owner"
  cowner1/d9s0d9a-3
  cowner2/slwl23ljsid0
"Question Content Owner"
  qowner1/asklh9231kl
  qowner2/saweidj2332l

Make the poll app modifiable in the admin

To tell the admin that Question objects have an admin interface, modify 'polls/admin.py'

from django.contrib import admin
from .models import Question

admin.site.register(Question)

References

https://docs.djangoproject.com/en/3.2/ref/models/relations/ https://docs.djangoproject.com/en/3.2/topics/db/queries/#field-lookups-intro https://docs.djangoproject.com/en/3.2/topics/db/queries/

Clone this wiki locally