This article is a series of steps through Django's official tutorials. This time, we'll move on to the second article, "Creating your first Django app, part 2."
Django tutorial summary for beginners by beginners ① (project creation ~) Django tutorial summary for beginners by beginners ② (Model, Admin) Django tutorial summary for beginners by beginners ③ (View) Django tutorial summary for beginners by beginners ④ (Generic View) Django tutorial summary for beginners by beginners ⑤ (test) Django tutorial summary for beginners by beginners ⑥ (static file) Summary of Django tutorials for beginners by beginners ⑦ (Customize Admin)
https://docs.djangoproject.com/ja/3.0/intro/tutorial02/
By default, Django uses SQlite.
Set the Database in mysite / settings.py
.
mysite/settings.py
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
Change your DB by changing ENGINE to django.db.backends.sqlite3
, django.db.backends.postgresql
, django.db.backends.mysql
or django.db.backends.oracle
I can do it.
Other than that, it is necessary to add settings such as ʻUSER,
PASSWORD and
HOST` depending on the DB.
For the time being, since it is a tutorial, I would like to go with SQLite as it is.
Since it is necessary to create a DB like Rails etc., migrate with the following command.
$ python manage.py migrate
Let's take a look at the other mysite / settings.py
.
Set the time zone you want to set in TIME_ZONE
.
ʻINSTALLED_APPS` lists the Django applications that are enabled in your project.
Let's go back to the polls app and create a model.
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.ForeignKey(Question, on_delete=models.CASCADE)
choice_text = models.CharField(max_length=200)
votes = models.IntegerField(default=0)
I'm a Python beginner, in the class Question (models.Model):
part? have become. This seems to indicate that the Question
class is a subclass of models.Model
(more precisely, django.db.models.Model
).
The content is easy to understand once you read it.
Each table of DB is represented as a class, and each field is represented by an instance in it.
You can also see that each field is specified with default values and conditions as arguments.
You can also see that Choice is tied to Question in the Choice class.
Activate the previous model.
Go back to mysite / settings.py
and add polls.apps.PollsConfig
inside ʻINSTALLED_APPS`.
mysite/settings.py
INSTALLED_APPS = [
'polls.apps.PollsConfig',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]
You have now added the application to your project.
Next, generate a migration file that adds tables etc. to the DB.
$ python manage.py makemigrations polls
The generated migration file has this format.
polls/migrations/0001_initial.py
# Generated by Django 3.0.1 on 2020-01-02 09:09
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
initial = True
dependencies = [
]
operations = [
migrations.CreateModel(
name='Question',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('question_text', models.CharField(max_length=200)),
('pub_date', models.DateTimeField(verbose_name='date published')),
],
),
migrations.CreateModel(
name='Choice',
fields=[
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
('choice_text', models.CharField(max_length=200)),
('votes', models.IntegerField(default=0)),
('question', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='polls.Question')),
],
),
]
Execute the migration with the following command
$ python manage.py migrate
$ python manage.py shell
You can now start the Django shell.
python
>>> from polls.models import Choice, Question # Import the model classes we just wrote.
# No questions are in the system yet.
>>> Question.objects.all()
<QuerySet []>
# 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(2012, 2, 26, 13, 0, 0, 775217, tzinfo=<UTC>)
# 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()
<QuerySet [<Question: Question object (1)>]>
You can also play with the DB in Shell. (I've never done it, but can I do it with Rails or Phoenix?)
At the very end, <QuerySet [<Question: Question object (1)>]>
, it is difficult to understand what kind of object exists, so add __str__ ()
to polls / models.py
.
It seems that __str__ ()
in Python is one of the special methods that returns an object as a string.
Basic special methods and str
polls/models.py
from django.db import models
class Question(models.Model):
# ...
def __str__(self):
return self.question_text
class Choice(models.Model):
# ...
def __str__(self):
return self.choice_text
Let's add another method to the Question class.
polls/models.py
import datetime
from django.db import models
from django.utils import timezone
class Question(models.Model):
# ...
def was_published_recently(self):
return self.pub_date >= timezone.now() - datetime.timedelta(days=1)
Click here for timedelta was_published_recently returns whether the Question passed as an argument was posted within 1 day from the current time.
Let's actually try these in Shell.
python
>>> from polls.models import Choice, Question
# Make sure our __str__() addition worked.
>>> Question.objects.all()
<QuerySet [<Question: Whats up?>]>
# Django provides a rich database lookup API that's entirely driven by
# keyword arguments.
>>> Question.objects.filter(id=1)
<QuerySet [<Question: Whats up?>]>
>>> Question.objects.filter(question_text__startswith='What')
<QuerySet [<Question: Whats up?>]>
# 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)
<Question: Whats up?>
# 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)
<Question: Whats up?>
# 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()
<QuerySet []>
# Create three choices.
>>> q.choice_set.create(choice_text='Not much', votes=0)
<Choice: Not much>
>>> q.choice_set.create(choice_text='The sky', votes=0)
<Choice: The sky>
>>> c = q.choice_set.create(choice_text='Just hacking again', votes=0)
# Choice objects have API access to their related Question objects.
>>> c.question
<Question: Whats up?>
# And vice versa: Question objects get access to Choice objects.
>>> q.choice_set.all()
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
>>> 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)
<QuerySet [<Choice: Not much>, <Choice: The sky>, <Choice: Just hacking again>]>
# Let's delete one of the choices. Use delete() for that.
>>> c = q.choice_set.filter(choice_text__startswith='Just hacking')
>>> c.delete()
Please refer to the following articles for the filter
etc. that appear in this.
Model-Basics of Data Access
Create an admin user
$ python manage.py createsuperuser
This will prompt you to enter the user name, etc., so enter it appropriately.
Start the server.
$ python manage.py runserver
And when you access http://127.0.0.1:8000/admin/
The admin login screen will appear like this, so enter the one you set earlier and log in.
![スクリーンショット 2020-01-02 20.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417600/34fc34d0-bdd5-9bda-1964-21c9a605f886. png)
If you log in successfully, you will be taken to a screen like this. Currently only groups and users can be edited.
polls/admin.py
from django.contrib import admin
from .models import Question
admin.site.register(Question)
You should now see the Questions on the admin site
Try pressing Question.
You can create new questions on this page.
Also, what's UP? Created in Shell earlier is displayed. When you press it, the edit form will be displayed as shown below.
From here you can also edit the Question, view the edit history, and more.
Recommended Posts