blank¶
Field.blank¶
If True, the field is allowed to be blank. Default is False.
Note that this is different than null. null is purely database-related, whereas blank is validation-related. If a field has blank=True, form validation will allow entry of an empty value. If a field has blank=False, the field will be required.
- User model
avatar = models.ImageField(blank=True)
gender = models.CharField(choices=GENDER_CHOICES, max_length=10, blank=True)
bio = models.TextField(default="", blank=True)
birthday = models.DateField(blank=True, null=True)
language = models.CharField(choices=LANG_CHOICES, max_length=2, blank=True)
currency = models.CharField(choices=CURRENCY_CHOICES, max_length=3, blank=True)
superhost = models.BooleanField(default=False)
- Created user table
-> only blank=True option not allow Null : “avatar” varchar(100) NOT NULL
sqlite> .schema users_user
CREATE TABLE IF NOT EXISTS "users_user" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "password" varchar(128) NOT NULL, "last_login" datetime NULL, "is_superuser" bool NOT NULL, "username" varchar(150) NOT NULL UNIQUE, "first_name" varchar(30) NOT NULL, "last_name" varchar(150) NOT NULL, "email" varchar(254) NOT NULL, "is_staff" bool NOT NULL, "is_active" bool NOT NULL, "date_joined" datetime NOT NULL, "avatar" varchar(100) NOT NULL, "gender" varchar(10) NOT NULL, "bio" text NOT NULL, "birthday" date NULL, "language" varchar(2) NOT NULL, "currency" varchar(3) NOT NULL, "superhost" bool NOT NULL);
◾️ abstract time stamp field
<class Meta: abstract = True> do not create table
<auto_now_add=True> Auto Model Created Time
<auto_now=True> Auto Model Updated Time
from django.db import models
# Create your models here.
class AbstractTimeStampModel(models.Model):
""" Time Stamped Model """
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
- usage of abstract time stamp
from django.db import models
from core import models as core_models
# Create your models here.
class Room(core_models.AbstractTimeStampModel):
""" Room Model Definition """
name = models.CharField(max_length=140)
◾️ third-party countries field
- settings.py
THIRD_PARTY_APPS = ["django_countries"]
- usage
header import(このような順番で定義すると分かりやすい)
python > django > third party > user defined
from django.db import models
from django_countries.fields import CountryField
from core import models as core_models
# Create your models here.
class Room(core_models.AbstractTimeStampModel):
""" Room Model Definition """
# https://github.com/SmileyChris/django-countries
country = CountryField()
◾️ foreigin key
- rooms model : Many(rooms) to One(user) relation
from django.db import models
from django_countries.fields import CountryField
from core import models as core_models
from users import models as user_models
# Create your models here.
class Room(core_models.AbstractTimeStampModel):
""" Room Model Definition """
name = models.CharField(max_length=140)
........
instant_book = models.BooleanField(default=False)
host = models.ForeignKey(user_models.User, on_delete=models.CASCADE)
- created rooms
sqlite> .schema rooms_room
CREATE TABLE IF NOT EXISTS "rooms_room" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "updated" datetime NOT NULL, "name" varchar(140) NOT NULL, "description" text NOT NULL, "country" varchar(2) NOT NULL, "city" varchar(80) NOT NULL, "price" integer NOT NULL, "address" varchar(140) NOT NULL, "guests" integer NOT NULL, "beds" integer NOT NULL, "bedrooms" integer NOT NULL, "baths" integer NOT NULL, "check_in" time NOT NULL, "check_out" time NOT NULL, "instant_book" bool NOT NULL
, "host_id" integer NOT NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED); CREATE INDEX "rooms_room_host_id_7f45f18c" ON "rooms_room" ("host_id");
sqlite>
◾️ paintjs for web draw
◾️ One to Many relation Many to Many relation
- rooms have only one user ( many to one )
- rooms have many room type ( many to many)
from django.db import models
from django_countries.fields import CountryField
from core import models as core_models
from users import models as user_models
# Create your models here.
class AbstractItem(core_models.AbstractTimeStampModel):
""" Abstract Item """
name = models.CharField(max_length=80)
class Meta:
abstract = True
def __str__(self):
return self.name
class RoomType(AbstractItem):
pass
class Room(core_models.AbstractTimeStampModel):
""" Room Model Definition """
name = models.CharField(max_length=140)
.......
host = models.ForeignKey(user_models.User, on_delete=models.CASCADE)
room_type = models.ManyToManyField(RoomType, blank=True)
def __str__(self):
return self.name
- admin panel for Room and RoomType
from django.contrib import admin
from . import models
# Register your models here.
@admin.register(models.RoomType)
class ItemAdmin(admin.ModelAdmin):
""" Custom Item Admin """
pass
@admin.register(models.Room)
class RoomAdmin(admin.ModelAdmin):
""" Custom Rooms Admin """
pass
- show admin
- show created table
sqlite> .schema rooms_room
CREATE TABLE IF NOT EXISTS "rooms_room" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "updated" datetime NOT NULL, "name" varchar(140) NOT NULL, "description" text NOT NULL, "country" varchar(2) NOT NULL, "city" varchar(80) NOT NULL, "price" integer NOT NULL, "address" varchar(140) NOT NULL, "guests" integer NOT NULL, "beds" integer NOT NULL, "bedrooms" integer NOT NULL, "baths" integer NOT NULL, "check_in" time NOT NULL, "check_out" time NOT NULL, "instant_book" bool NOT NULL, "host_id" integer NOT NULL REFERENCES "users_user" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE INDEX "rooms_room_host_id_7f45f18c" ON "rooms_room" ("host_id");
sqlite> .schema rooms_roomtype
CREATE TABLE IF NOT EXISTS "rooms_roomtype" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "created" datetime NOT NULL, "updated" datetime NOT NULL, "name" varchar(80) NOT NULL);
sqlite> .schema rooms_room_room_type
CREATE TABLE IF NOT EXISTS "rooms_room_room_type" ("id" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "room_id" integer NOT NULL REFERENCES "rooms_room" ("id") DEFERRABLE INITIALLY DEFERRED, "roomtype_id" integer NOT NULL REFERENCES "rooms_roomtype" ("id") DEFERRABLE INITIALLY DEFERRED);
CREATE UNIQUE INDEX "rooms_room_room_type_room_id_roomtype_id_7630b1fa_uniq" ON "rooms_room_room_type" ("room_id", "roomtype_id");
CREATE INDEX "rooms_room_room_type_room_id_1b3ad525" ON "rooms_room_room_type" ("room_id");
CREATE INDEX "rooms_room_room_type_roomtype_id_aae49861" ON "rooms_room_room_type" ("roomtype_id");
sqlite> select * from rooms_roomtype;
1|2021-04-14 14:26:33.297073|2021-04-14 14:26:33.297106|Hotel Room
2|2021-04-14 14:26:43.709087|2021-04-14 14:26:43.709118|Shared Room
3|2021-04-14 14:26:52.727383|2021-04-14 14:26:52.727432|Private Room
4|2021-04-14 14:27:02.231116|2021-04-14 14:27:02.231150|Entire Room
◾️ Register serveral model with one class for admin panel
- define models
# Create your models here.
class AbstractItem(core_models.AbstractTimeStampModel):
""" Abstract Item """
name = models.CharField(max_length=80)
class Meta:
abstract = True
def __str__(self):
return self.name
class RoomType(AbstractItem):
""" Ro0mType Model Definition """
pass
class Amenity(AbstractItem):
""" Amenity Model Definition """
pass
class HouseRule(AbstractItem):
""" HouseRule Model Definition """
pass
class Facility(AbstractItem):
""" Amenity Model Definition """
pass
- register RoomType and Amenity
# Register your models here.
@admin.register(models.RoomType, models.Facility, models.Amenity, models.HouseRule)
class ItemAdmin(admin.ModelAdmin):
""" Custom Item Admin """
pass
- Check names on admin panel
-> we need to change the naming rule
- Ammenitys->Ammenities
- House rules->House Rules
◾️ Change naming rule of Admin panel
- class meta for naming
class AbstractItem(core_models.AbstractTimeStampModel):
""" Abstract Item """
name = models.CharField(max_length=80)
class Meta:
abstract = True
def __str__(self):
return self.name
class RoomType(AbstractItem):
""" Ro0mType Model Definition """
class Meta:
verbose_name = "Room Type"
class Amenity(AbstractItem):
""" Amenity Model Definition """
class Meta:
verbose_name_plural = "Amenities"
class HouseRule(AbstractItem):
""" HouseRule Model Definition """
class Meta:
verbose_name = "House Rule"
class Facility(AbstractItem):
""" Amenity Model Definition """
class Meta:
verbose_name_plural = "Facilities"
- check admin panel
◾️ ForeignKey : set model name as string
- models.ForeignKey(Room, on_delete=models.CASCADE): need to import model
- models.ForeignKey(“Room”, on_delete=models.CASCADE): Not need import model
◾️ related_name
-> If related_name is not exist, it cause Reverse accessor clash
class User(models.Model):
author = models.ForeignKey('category.Category', related_name='author_user')
editor = models.ForeignKey('category.Category', related_name='editor_user')
◾️ routing example
from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path("", include("core.urls", namespace="core")),
path("movies", include("movies.urls", namespace="movies")),
path("books", include("books.urls", namespace="books")),
path("genres", include("categories.urls", namespace="genres")),
path("people", include("people.urls", namespace="people")),
path("admin/", admin.site.urls),
]
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
from django.urls import path
from movies.views import resolve_movies
app_name="movies"
urlpatterns = [
path("", resolve_movies, name="movies")
]
from django.shortcuts import render
def resolve_movies(request):
return render(request, "movies.html")
Generally, slicing a QuerySet
returns a new QuerySet
This returns the sixth through tenth objects (OFFSET 5 LIMIT 5):
Entry.objects.all()[5:10]
◾️ check GET param
- http://127.0.0.1:8000/?page=1&save=none
print(request.GET.keys())
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
dict_keys(['page', 'save'])
- http://127.0.0.1
if page query is not exist, default page=0
print(request.GET.get("page", 0))
Starting development server at http://127.0.0.1:8000/
Quit the server with CONTROL-C.
0
- manual page
http://127.0.0.1:8000/?page=1
http://127.0.0.1:8000/?page=2
this code covers [http://127.0.0.1:8000/?page=]
def all_rooms(request):
# print(dir(request.GET))
page = request.GET.get("page", 1)
page = int(page or 1)
page_size = 10
limit = page_size * page
offset = limit - page_size
all_rooms = models.Room.objects.all()[offset:limit]
return render(request, "rooms/home.html", context={"rooms": all_rooms})
Adds the argument to the value.
For example:
{{ value|add:"2" }}
this code do not fetch data immediately
room_list = models.Room.objects.all() -> not load data
-> if we code “print(room_list)”, this call fetch data from db
def all_rooms(request):
# print(dir(request.GET))
page = request.GET.get("page")
room_list = models.Room.objects.all()
QuerySets are lazy – the act of creating a QuerySet doesn’t involve any database activity. You can stack filters together all day long, and Django won’t actually run the query until the QuerySet is evaluated. Take a look at this example:
def all_rooms(request):
# print(dir(request.GET))
page = request.GET.get("page")
room_list = models.Room.objects.all()
paginator = Paginator(room_list, 10, orphans=5)
rooms = paginator.get_page(page)
#print(vars(rooms.paginator))
return render(request, "rooms/home.html", {"page": rooms})
{% extends "base.html" %}
{% block page_name %}
Room | airbnb
{% endblock page_name %}
{% block content %}
{% for room in page.object_list %}
<h2>{{room.name}} | ¥{{room.price}}</h2>
{% endfor %}
<h5>
{% if page.has_previous %}
<a href="?page={{page.number|add:-1}}"><</a>
{% endif %}
page {{page.number}} of {{page.paginator.num_pages}}
{% if page.has_next %}
<a href="?page={{page.number|add:1}}">></a>
{% endif %}
</h5>
{% for p in page.paginator.page_range %}
<a href="?page={{p}}">{{p}} </a>
{% endfor %}
{% endblock %}
◾️paginator.get_page() or paginator.page()
paginator.page control more exception
def all_rooms(request):
# print(dir(request.GET))
page = request.GET.get("page", 1)
room_list = models.Room.objects.all()
paginator = Paginator(room_list, 10, orphans=5)
try:
rooms = paginator.page(int(page))
return render(request, "rooms/home.html", {"page": rooms})
except EmptyPage:
return redirect("/")
◾️ reverse ex for url
from django.urls import reverse
....
def get_absolute_url(self):
return reverse("rooms:detail", kwargs={"pk": self.pk})
def room_detail(request, pk):
print(pk)
try:
room = models.Room.objects.get(pk=pk)
return render(request, "rooms/detail.html", {"room": room})
except models.Room.DoesNotExist:
# return redirect("")
return redirect(reverse("core:home"))
◾️ redirect or Http404
- use redirect home
from django.shortcuts import render, redirect
....
def room_detail(request, pk):
print(pk)
try:
room = models.Room.objects.get(pk=pk)
return render(request, "rooms/detail.html", {"room": room})
except models.Room.DoesNotExist:
# return redirect("")
return redirect(reverse("core:home"))
2. use Http404 for request error
from django.http import Http404
def room_detail(request, pk):
print(pk)
try:
room = models.Room.objects.get(pk=pk)
return render(request, "rooms/detail.html", {"room": room})
except models.Room.DoesNotExist:
raise Http404()
3. use templates 404.html for Http404() exception
{% extends "base.html" %}
{% block page_name %}
404 Error
{% endblock page_name %}
{% block content %}
<h1>Not found request page</h1>
{% endblock %}
◾️FBV(Function based View) VS CBV(Class based View)
- FBV
templates/rooms/detail.html
app_name = "rooms"
urlpatterns = [
path("<int:pk>", room_views.room_detail, name="detail"),
]
def room_detail(request, pk):
print(pk)
try:
room = models.Room.objects.get(pk=pk)
return render(request, "rooms/detail.html", {"room": room})
except models.Room.DoesNotExist:
raise Http404()
2. CBV
templates/rooms/room_detail.html
app_name = "rooms"
urlpatterns = [
path("<int:pk>", room_views.room_detail.as_view(), name="detail"),
]
from django.views.generic import ListView, DetailView
class room_detail(DetailView):
""" RoomDetail Definition """
model = models.Room
◾️db search : field lookups