본문 바로가기

Development (Python, Django, C..)

[Django] Tutorial 따라하기 - 2

* Reference : https://docs.djangoproject.com/ko/2.1/intro/tutorial02/ 

 

첫 번째 장고 앱 작성하기, part 2 | Django 문서 | Django

Django The web framework for perfectionists with deadlines. Overview Download Documentation News Community Code Issues About ♥ Donate

docs.djangoproject.com

 

#. Create DB 


- Define db and environment

(djenv) ivan@django:~/djgo$ more mysite/settings.py
~~~ 
# Database 
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases 

DATABASES = { 
    'default': { 
        'ENGINE': 'django.db.backends.sqlite3', 
        'NAME': os.path.join(BASE_DIR+'/db', 'db.sqlite3'), 
    } 
} 
~~~ 


- Make directory for DB

더보기

(djenv) ivan@django:~/djgo$ mkdir db 
(djenv) ivan@django:~/djgo$ ls -al 
total 28 
drwxrwxr-x 6 ivan ivan 4096 Nov 19 13:04 . 
drwxr-xr-x 6 ivan ivan 4096 Nov 18 13:11 .. 
drwxrwxr-x 2 ivan ivan 4096 Nov 19 13:04 db 
drwxrwxr-x 6 ivan ivan 4096 Nov 12 09:19 djenv 
-rwxrwxr-x 1 ivan ivan  538 Nov 18 12:31 manage.py 
drwxrwxr-x 3 ivan ivan 4096 Nov 18 12:32 mysite 
drwxrwxr-x 4 ivan ivan 4096 Nov 18 13:09 polls 


- Migrate : Nothing to do with DB

(djenv) ivan@django:~/djgo$ python manage.py migrate 
Operations to perform: 
  Apply all migrations: admin, auth, contenttypes, sessions 
Running migrations: 
  Applying contenttypes.0001_initial... OK 
  Applying auth.0001_initial... OK 
  Applying admin.0001_initial... OK 
  Applying admin.0002_logentry_remove_auto_add... OK 
  Applying contenttypes.0002_remove_content_type_name... OK 
  Applying auth.0002_alter_permission_name_max_length... OK 
  Applying auth.0003_alter_user_email_max_length... OK 
  Applying auth.0004_alter_user_username_opts... OK 
  Applying auth.0005_alter_user_last_login_null... OK 
  Applying auth.0006_require_contenttypes_0002... OK 
  Applying auth.0007_alter_validators_add_error_messages... OK 
  Applying auth.0008_alter_user_username_max_length... OK 
  Applying auth.0009_alter_user_last_name_max_length... OK 
  Applying sessions.0001_initial... OK 
(djenv) ivan@django:~/djgo$ 





#. Create Model


- define models

(djenv) ivan@django:~/djgo$ more polls/models.py
from django.db import models 

class Question(models.Model): 
    question_text = models.CharField    (max_length=200) 
    pub_date      = models.DateTimeField('date published') 
     
class Choice(models.Model): 
    question    = models.ForeighKey  (Question, on_delete=models.CASCADE) 
    choice_text = models.CharField   (max_length=200) 
    votes       = models.IntegerField(default=0) 

 


- Check location of PollsConfig Class --> This have to be registered on settings.py

 

(djenv) ivan@django:~/djgo$ more polls/apps.py
from django.apps import AppConfig 


class PollsConfig(AppConfig): 
    name = 'polls' 



- register polls app to server 

 

(djenv) ivan@django:~/djgo$ more mysite/settings.py
~~~ 
# Application definition 

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

~~~ 



- Save as migrations -> Occurs error

더보기

(djenv) ivan@django:~/djgo$ python manage.py makemigrations polls 
Traceback (most recent call last): 
  File "manage.py", line 15, in  
    execute_from_command_line(sys.argv) 
  File "/home/ivan/djgo/djenv/lib/python3.6/site-packages/django/core/management/__init__.py", line 371, in execute_from_command_line 
    utility.execute() 
  File "/home/ivan/djgo/djenv/lib/python3.6/site-packages/django/core/management/__init__.py", line 347, in execute 
    django.setup() 
  File "/home/ivan/djgo/djenv/lib/python3.6/site-packages/django/__init__.py", line 24, in setup 
    apps.populate(settings.INSTALLED_APPS) 
  File "/home/ivan/djgo/djenv/lib/python3.6/site-packages/django/apps/registry.py", line 112, in populate 
    app_config.import_models() 
  File "/home/ivan/djgo/djenv/lib/python3.6/site-packages/django/apps/config.py", line 198, in import_models 
    self.models_module = import_module(models_module_name) 
  File "/usr/lib/python3.6/importlib/__init__.py", line 126, in import_module 
    return _bootstrap._gcd_import(name[level:], package, level) 
  File "", line 994, in _gcd_import 
  File "", line 971, in _find_and_load 
  File "", line 955, in _find_and_load_unlocked 
  File "", line 665, in _load_unlocked 
  File "", line 678, in exec_module 
  File "", line 219, in _call_with_frames_removed 
  File "/home/ivan/djgo/polls/models.py", line 7, in  
    class Choice(models.Model): 
  File "/home/ivan/djgo/polls/models.py", line 8, in Choice 
    question    = models.ForeighKey  (Question, on_delete=models.CASCADE) 
AttributeError: module 'django.db.models' has no attribute 'ForeighKey' 
(djenv) ivan@django:~/djgo$ 


- Fix the error

(djenv) ivan@django:~/djgo$ more polls/models.py
~~     
class Choice(models.Model): 
    question    = models.ForeignKey  (Question, on_delete=models.CASCADE) 
~~ 

 


- Retry to save as migrations

(djenv) ivan@django:~/djgo$ python manage.py makemigrations polls 
Migrations for 'polls': 
  polls/migrations/0001_initial.py 
    - Create model Choice 
    - Create model Question 
    - Add field question to choice 
(djenv) ivan@django:~/djgo$ 

 


- Check the sql which is executed

(djenv) ivan@django:~/djgo$ python manage.py sqlmigrate polls 0001 
BEGIN; 
-- 
-- Create model Choice 
-- 
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL); 
-- 
-- Create model Question 
-- 
CREATE TABLE "polls_question" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "question_text" varchar(200) NOT NULL, "pub_date" datetime NOT NULL); 
-- 
-- Add field question to choice 
-- 
ALTER TABLE "polls_choice" RENAME TO "polls_choice__old"; 
CREATE TABLE "polls_choice" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "choice_text" varchar(200) NOT NULL, "votes" integer NOT NULL, "question_id" integer NOT NULL REFERENCES "polls_question" ("id") DEFERRABLE INITIALLY DEFERRED); 
INSERT INTO "polls_choice" ("id", "choice_text", "votes", "question_id") SELECT "id", "choice_text", "votes", NULL FROM "polls_choice__old"; 
DROP TABLE "polls_choice__old"; 
CREATE INDEX "polls_choice_question_id_c5b4b260" ON "polls_choice" ("question_id"); 
COMMIT; 
(djenv) ivan@django:~/djgo$ 

 

 

- Migrate using saved migrations

(djenv) ivan@django:~/djgo$ python manage.py migrate 
Operations to perform: 
  Apply all migrations: admin, auth, contenttypes, polls, sessions 
Running migrations: 
  Applying polls.0001_initial... OK 
(djenv) ivan@django:~/djgo$ 

 

 

 


 

#. Using Python shell 



-- Get into python shell

(djenv) ivan@django:~/djgo$ python manage.py shell 
Python 3.6.8 (default, Oct  7 2019, 12:59:55) 
[GCC 8.3.0] on linux 
Type "help", "copyright", "credits" or "license" for more information. 
(InteractiveConsole) 
>>> 

>>> from polls.models import Choice, Question  # Import the model classes we just wrote. 

# No questions are in the system yet. 
>>> Question.objects.all() 


# Create a new Question. 
# Support for time zones is enabled in the default settings file, so 
# Django expects a datetime with tzinfo for pub_date. Use timezone.now() 
# instead of datetime.datetime.now() and it will do the right thing. 
>>> from django.utils import timezone 
>>> q = Question(question_text="What's new?", pub_date=timezone.now()) 

# Save the object into the database. You have to call save() explicitly. 
>>> q.save() 

# Now it has an ID. 
>>> q.id 
1 

# Access model field values via Python attributes. 
>>> q.question_text 
"What's new?" 
>>> q.pub_date 
datetime.datetime(2019, 11, 19, 13, 53, 39, 523002, tzinfo=) 

# Change values by changing the attributes, then calling save(). 
>>> q.question_text = "What's up?" 
>>> q.save() 

# objects.all() displays all the questions in the database. 
>>> Question.objects.all() 
]> 

 


- Change model.py to change result of objects.all()

 

(djenv) ivan@django:~/djgo$ more polls/models.py 
import datetime 

from django.db    import models 
from django.utils import timezone 


class Question(models.Model): 
    question_text = models.CharField    (max_length=200) 
    pub_date      = models.DateTimeField('date published') 

    def __str__(self): 
        return self.question_text 

    def was_published_recently(self): 
        return self.pub_date >= timezone.now() - datetime.timedelta(days=1) 


class Choice(models.Model): 
    question    = models.ForeignKey  (Question, on_delete=models.CASCADE) 
    choice_text = models.CharField   (max_length=200) 
    votes       = models.IntegerField(default=0) 

    def __str__(self): 
        return self.choice_text 




-- Check again on python shell

>>> from polls.models import Choice, Question 

# Make sure our __str__() addition worked. 
>>> Question.objects.all() 
]> 

# Django provides a rich database lookup API that's entirely driven by 
# keyword arguments. 
>>> Question.objects.filter(id=1) 
]> 
>>> Question.objects.filter(question_text__startswith='What') 
]> 

# Get the question that was published this year. 
>>> from django.utils import timezone 
>>> current_year = timezone.now().year 
>>> Question.objects.get(pub_date__year=current_year) 


# Request an ID that doesn't exist, this will raise an exception. 
>>> Question.objects.get(id=2) 
Traceback (most recent call last): 
    ... 
DoesNotExist: Question matching query does not exist. 

# Lookup by a primary key is the most common case, so Django provides a 
# shortcut for primary-key exact lookups. 
# The following is identical to Question.objects.get(id=1). 
>>> Question.objects.get(pk=1) 


# Make sure our custom method worked. 
>>> q = Question.objects.get(pk=1) 
>>> q.was_published_recently() 
True 

# Give the Question a couple of Choices. The create call constructs a new 
# Choice object, does the INSERT statement, adds the choice to the set 
# of available choices and returns the new Choice object. Django creates 
# a set to hold the "other side" of a ForeignKey relation 
# (e.g. a question's choice) which can be accessed via the API. 
>>> q = Question.objects.get(pk=1) 

# Display any choices from the related object set -- none so far. 
>>> q.choice_set.all() 


# Create three choices. 
>>> q.choice_set.create(choice_text='Not much', votes=0) 

>>> q.choice_set.create(choice_text='The sky', votes=0) 

>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0) 

# Choice objects have API access to their related Question objects. 
>>> c.question 


# And vice versa: Question objects get access to Choice objects. 
>>> q.choice_set.all() 
, , ]> 
>>> q.choice_set.count() 
3 

# The API automatically follows relationships as far as you need. 
# Use double underscores to separate relationships. 
# This works as many levels deep as you want; there's no limit. 
# Find all Choices for any question whose pub_date is in this year 
# (reusing the 'current_year' variable we created above). 
>>> Choice.objects.filter(question__pub_date__year=current_year) 
, , ]> 

# Let's delete one of the choices. Use delete() for that. 
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking') 
>>> c.delete() 







#. Django Admin 


-- Create super-user

(djenv) ivan@django:~/djgo$ python manage.py createsuperuser
Username (leave blank to use 'ivan'): admin
Email address: admin@example.com
Password:
Password (again):
This password is too short. It must contain at least 8 characters.
Password:
Password (again):
Superuser created successfully.
(djenv) ivan@django:~/djgo$



-- Run server

(djenv) ivan@django:~/djgo$ python manage.py runserver 0:8000 
Performing system checks... 

System check identified no issues (0 silenced). 
November 19, 2019 - 14:16:03 
Django version 2.0.13, using settings 'mysite.settings' 
Starting development server at http://0:8000/ 
Quit the server with CONTROL-C. 



-- Check on browser : http://192.168.56.200:8000/admin/login/?next=/admin/



-- modify admin.py

(djenv) ivan@django:~/djgo$ more polls/admin.py 
from django.contrib import admin 

from .models import Question 

admin.site.register(Question) 

'Development (Python, Django, C..)' 카테고리의 다른 글

[Django] Tutorial 따라하기 - 4  (0) 2019.11.27
[Django] Tutorial 따라하기 - 3  (0) 2019.11.23
[Django] Tutorial 따라하기 - 1  (0) 2019.11.19
[Django] Starting Django!!  (1) 2019.11.16
[Python] File I/O  (0) 2019.04.27