from django.db import models
class Admin(models.Model):
"""管理员"""
username = models.CharField(verbose_name="用户名", max_length=32)
password = models.CharField(verbose_name="密码", max_length=64)
class Department(models.Model):
"""部门列表"""
# id = models.AutoField(verbose_name="ID", primary_key=True) 默认帮我们写了 不用写id
title = models.CharField(verbose_name="标题", max_length=32)
def __str__(self):
return self.title
class UserInfo(models.Model):
"""员工表"""
name = models.CharField(verbose_name="姓名", max_length=16)
password = models.CharField(verbose_name="密码", max_length=64)
age = models.IntegerField(verbose_name="年龄")
account = models.DecimalField(verbose_name="账户余额", max_digits=10, decimal_places=2, default=0)
# create_time = models.DateTimeField(verbose_name="入职时间")
create_time = models.DateField(verbose_name="入职时间")
depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.CASCADE) # on_delete=models.CASCADE级联删除
"""depart = models.ForeignKey(to="Department", to_field="id", on_delete=models.SET_NULL, null=True, blank=True)
on_delete=models.SET_NULL置空null=True blank=True并且为空 """
gender_choices = (
(1, "男"),
(2, "女"),
)
gender = models.SmallIntegerField(verbose_name="性别", choices=gender_choices)
class PrettyNum(models.Model):
"""靓号表"""
mobile = models.CharField(verbose_name="手机号", max_length=11)
# 想要允许为空 null=True, blank=True
price = models.IntegerField(verbose_name="价格", default=0)
level_choices = (
(1, "1级"),
(2, "2级"),
(3, "3级"),
(4, "4级"),
)
level = models.SmallIntegerField(verbose_name="级别", choices=level_choices, default=1)
status_choices = (
(1, "已占用"),
(2, "未占用"),
)
status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=2)
# 订单
class Order(models.Model):
"""订单"""
oid = models.CharField(verbose_name="订单号", max_length=64)
title = models.CharField(verbose_name="名称", max_length=32)
price = models.IntegerField(verbose_name="价格")
status_choices = (
(1, "待支付"),
(2, "已支付"),
)
status = models.SmallIntegerField(verbose_name="状态", choices=status_choices, default=1)
admin = models.ForeignKey(verbose_name="管理员", to="Admin", on_delete=models.CASCADE)
views.py
from django.shortcuts import render, redirect, HttpResponse
from app01 import models
from django import forms # ModelForm引入
from django.core.validators import RegexValidator # 校验的引入 (校验一)
from django.core.exceptions import ValidationError # 也是校验 (校验二)
from app01.utils.pagination import Pagination
from app01.utils.encrypt import md5
from app01.utils. code import check_code
from io import BytesIO
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
def depart_list(request):
"""部门列表"""
# 获取session
info_dict = request.session["info"]
print(info_dict) # {'id': 1, 'name': '郑建'}
print(info_dict["id"]) # 1
# 去数据库中获取所有的部门表
queryset = models.Department.objects.all()
return render(request, "depart_list.html", {"queryset": queryset})
def depart_add(request):
"""添加部门"""
if request.method == "GET":
return render(request, 'depart_add.html', )
# 获取用户POST提交过来的数据
title = request.POST.get("title")
models.Department.objects.create(title=title)
# 重定向回部门列表
return redirect("/depart/list/")
def depart_delete(request):
"""删除部门"""
# 获取id
nid = request.GET.get('nid')
# 删除
models.Department.objects.filter(id=nid).delete()
# 重定向回部门列表
return redirect("/depart/list/")
def depart_edit(request, nid):
"""修改部门"""
# 根据nid获取它的数据
if request.method == "GET":
row_object = models.Department.objects.filter(id=nid).first()
return render(request, "depart_edit.html", {"row_object": row_object})
title = request.POST.get("title")
models.Department.objects.filter(id=nid).update(title=title)
return redirect("/depart/list/")
def user_list(request):
"""用户管理"""
queryset = models.UserInfo.objects.all()
page_object = Pagination(request, queryset, page_size=2)
context = {
"queryset": page_object.page_queryset,
"page_string": page_object.html(),
}
return render(request, 'user_list.html', context)
def user_add(request):
"""用户添加"""
if request.method == "GET":
context = {
'gender_choices': models.UserInfo.gender_choices,
'depart_list': models.Department.objects.all()
}
return render(request, 'user_add.html', context)
name = request.POST.get('name')
password = request.POST.get('password')
age = request.POST.get('age')
account = request.POST.get('account')
ctime = request.POST.get('ctime')
gender = request.POST.get('gender')
depart_id = request.POST.get('depart_id')
models.UserInfo.objects.create(name=name, password=password, age=age, account=account, create_time=ctime,
gender=gender, depart_id=depart_id)
return redirect('/user/list/')
class UserModelForm(forms.ModelForm):
# name = forms.CharField(min_length=3, label="用户名") # 校验
class Meta:
model = models.UserInfo # 从哪个表拿数据
fields = ["name", "password", "age", "account", "create_time", "gender", "depart"] # 数组的元素是表中的字段
# 一个一个加类
# widgets = {
# # 给name字段加一个类form-control
# "name": forms.TextInput(attrs={"class": "form-control"}),
# "password": forms.TextInput(attrs={"class": "form-control"}),
# "age": forms.TextInput(attrs={"class": "form-control"}),
# "account": forms.TextInput(attrs={"class": "form-control"}),
# "create_time": forms.TextInput(attrs={"class": "form-control"}),
# "gender": forms.Select(attrs={"class": "form-control"}),
# "depart": forms.Select(attrs={"class": "form-control"}),
# }
# 批量添加
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
for name, field in self.fields.items():
field.widget.attrs = {"class": "form-control"}
def user_model_form_add(request):
"""添加用户modelform"""
if request.method == "GET":
form = UserModelForm() # 获取表中传过来的字段
return render(request, 'user_model_form_add.html', {"form": form})
form = UserModelForm(data=request.POST) # 获取提交的数据
if form.is_valid(): # 校验通过
# 添加数据到数据库
form.save() # 把检验通过的数据保存数据库中
return redirect('/user/list/')
return render(request, 'user_model_form_add.html', {"form": form}) #
def user_edit(request, nid):
"""用户编辑"""
it = models.UserInfo.objects.filter(id=nid).first()
if request.method == "GET":
form = UserModelForm(instance=it)
return render(request, 'user_edit.html', {"form": form})
form = UserModelForm(data=request.POST, instance=it) # 加instance=it就是说更新it这条数据 如果不写这个会新增加一条数据
if form.is_valid():
# 默认保存的是用户输入所有的数据,如果想要在用户输入以外增加一点值
# form.instance.字段名 = 值
form.save()
return redirect('/user/list/')
return render(request, 'user_edit.html', {"form": form})
def user_delete(request, nid):
models.UserInfo.objects.filter(id=nid).delete()
return redirect('/user/list/')
# def pretty_list(request):
# """靓号管理"""
# # for i in range(300):
# # models.PrettyNum.objects.create(mobile="18188888188", price=10, level=1, status=1)
#
# data_dict = {} # 定义一个空字典
# search_data = request.GET.get('q', "") # 获取get请求的值, 参数二是默认值
# if search_data: # 如果有值
# data_dict["mobile__contains"] = search_data
# # 1.根据用户想要的页码,计算起始位置
# page = int(request.GET.get('page', 1))
# page_size = 20
# start = (page - 1) * page_size
# end = page * page_size
# # select * from 表 order by level asc; asc是升序 desc是降序
# queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")[start:end] # id就是asc, -id就是desc
#
# total_count = models.PrettyNum.objects.filter(**data_dict).order_by("-level").count() # 获取数据库的总条数
# # 总页码
# total_page_count, div = divmod(total_count, page_size) # divmod(total_count, page_size): 相当于total_count / page_size,结构出来的值total_page_count是商,div是余
# if div:
# total_page_count += 1
#
# # 计算出显示当前页面的前5页、后五页
# plus = 5
# # start_page = page - plus
# # end_page = page + plus + 1
# if total_page_count <= 2 * plus + 1:
# # 数据库中的数据都没有到达11页的时候
# start_page = 1
# end_page = total_page_count
# else:
# # 数据库中的数据比较多> 11页时
# # 当前页<5时
# if page <= plus:
# start_page = 1
# end_page = 2 * plus
# else:
# # 当前页 > 5
# # 当前页+5 > 总页数
# if (page + plus) > total_page_count:
# start_page = total_page_count - 2 * plus
# end_page = total_page_count
# else:
# start_page = page - plus
# end_page = page + plus
# page_str_list = []
# page_str_list.append('<li><a href="?page={}">首页</a></li>'.format(1)) # 首页
# # 上一页
# if page > 1:
# prev = '<li><a href="?page={}">上一页</a></li>'.format(page - 1)
# else:
# prev = '<li><a href="?page={}">上一页</a></li>'.format(1)
# page_str_list.append(prev)
# # 生成前端页码标签
#
# for i in range(start_page, end_page + 1):
# if i == page:
# ele = '<li class="active"><a href="?page={}">{}</a></li>'.format(i, i)
# else:
# ele = '<li><a href="?page={}">{}</a></li>'.format(i, i) # format里面的两个参数分别按顺序填充字符串中的{}
# page_str_list.append(ele)
#
# # 下一页
# if page < total_page_count:
# prev = '<li><a href="?page={}">上一页</a></li>'.format(page + 1)
# else:
# prev = '<li><a href="?page={}">上一页</a></li>'.format(total_page_count)
# page_str_list.append(prev)
# page_str_list.append('<li><a href="?page={}">尾页</a></li>'.format(total_page_count)) # 尾页
# page_string = mark_safe("".join(page_str_list)) # "".join(page_str_list:字符串拼接, mark_safe:用这个方法包裹字符串的标签 在页面上显示的就不是字符串了而是标签
#
# return render(request, "pretty_list.html", {"queryset": queryset, "search_data": search_data, "page_string": page_string})
def pretty_list(request):
"""靓号管理"""
# for i in range(300):
# models.PrettyNum.objects.create(mobile="18188888188", price=10, level=1, status=1)
data_dict = {} # 定义一个空字典
search_data = request.GET.get('q', "") # 获取get请求的值, 参数二是默认值
if search_data: # 如果有值
data_dict["mobile__contains"] = search_data
queryset = models.PrettyNum.objects.filter(**data_dict).order_by("-level")
page_object = Pagination(request, queryset)
context = {
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html(), # 生成的页码
"search_data": search_data,
}
return render(request, "pretty_list.html", context)
class PrettyModelForm(forms.ModelForm):
# 校验方式一(正则表达试校验,他不能操作数据库)
# mobile = forms.CharField(
# label="手机号",
# validators=[RegexValidator(r'^1[3-9]\d{9}$', '手机号格式错误'), ],
# )
class Meta:
model = models.PrettyNum
fields = "__all__" # 获取列表的全部字段
# fields = ["mobile"] # 只获取mobile这个字段
# exclude = ["level"] # 排除level这个字段
widgets = {
"mobile": forms.TextInput(attrs={"class": "form-control"}),
"price": forms.TextInput(attrs={"class": "form-control"}),
"level": forms.Select(attrs={"class": "form-control"}),
"status": forms.Select(attrs={"class": "form-control"}),
}
# 校验二(钩子方法, 可以操作数据库)
def clean_mobile(self):
txt_mobile = self.cleaned_data["mobile"] # 校验字段 mobile
exists = models.PrettyNum.objects.filter(mobile=txt_mobile).exists() # 判断数据库是否存在相同的txt_mobile 有就返回true 反之false
if exists:
"""校验不通过"""
raise ValidationError("手机号已经存在")
# 校验通过,用户输入的返回值
return txt_mobile
def pretty_add(request):
"""添加靓号"""
if request.method == "GET":
form = PrettyModelForm()
return render(request, 'pretty_add.html', {"form": form})
form = PrettyModelForm(data=request.POST) # 获取post请求提交的数据
if form.is_valid():
form.save()
return redirect('/pretty/list/')
return render(request, 'pretty_add.html', {"form": form})
class PrettyEditModelForm(forms.ModelForm):
# mobile = forms.CharField(disabled=True, label="手机号") # 禁止输入 label名为手机号
class Meta:
model = models.PrettyNum
fields = ['mobile', 'price', 'level', 'status']
widgets = {
"mobile": forms.TextInput(attrs={"class": "form-control"}),
"price": forms.TextInput(attrs={"class": "form-control"}),
"level": forms.Select(attrs={"class": "form-control"}),
"status": forms.Select(attrs={"class": "form-control"}),
}
# 校验二(钩子方法, 可以操作数据库)
def clean_mobile(self):
# print(self.instance.pk) # self.instance.pk表示id
txt_mobile = self.cleaned_data["mobile"] # 校验字段 mobile
# 先排除后过滤
# exists:判断数据库是否存在相同的txt_mobile 有就返回true 反之false, exckude(id=self.instance.pk):处理当前id外
exists = models.PrettyNum.objects.exckude(id=self.instance.pk).filter(mobile=txt_mobile).exists()
if exists:
"""校验不通过"""
raise ValidationError("手机号已经存在")
# 校验通过,用户输入的返回值
return txt_mobile
def pretty_edit(request, nid):
"""靓号编辑"""
row_object = models.PrettyNum.objects.filter(id=nid).first()
if request.method == "GET":
form = PrettyEditModelForm(instance=row_object)
return render(request, 'pretty_edit.html', {"form": form})
form = PrettyEditModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/pretty/list/')
return render(request, 'pretty_edit.html', {"form": form})
def pretty_delete(request, nid):
models.PrettyNum.objects.filter(id=nid).delete()
return redirect('/pretty/list/')
def admin_list(request):
"""管理员列表"""
# 检查用户是否已登录,已登录,继续走下去,未登录,跳转回登录页面。
# 用户发过来的请求,获取cookie随机字符串,拿着随机字符串看看session中有没有
# request.session["info"]: 设置session
info = request.session.get('info')
if not info:
return redirect('/login/')
queryset = models.Admin.objects.all()
page_object = Pagination(request, queryset, page_size=3)
context = {
"queryset": page_object.page_queryset,
"page_string": page_object.html(),
}
return render(request, 'admin_list.html', context)
class AdminModelForm(forms.ModelForm):
confirm_password = forms.CharField(
label="确认密码",
widget=forms.PasswordInput(attrs={"class": "form-control"})
)
class Meta:
model = models.Admin
fields = ["username", "password", "confirm_password"]
widgets = {
"username": forms.TextInput(attrs={"class": "form-control"}),
"password": forms.PasswordInput(attrs={"class": "form-control"}, render_value=True) # 密码框密码不对不会自动清空
}
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
def clean_confirm_password(self): # 切记当前的方法名可不是谁便乱起的 以clean_开头后面写哪个字段返回值就给哪个字段 值会存储到数据库里
pwd = self.cleaned_data.get("password")
confirm = md5(self.cleaned_data.get("confirm_password")) # 因为上面的密码已经加密了 这里我们也要让确认密码加密 加密的密码与加密的确认密码进行比较
if confirm != pwd:
raise ValidationError("密码不一致")
return confirm # 为什么返回这个值 返回这个值会保存到form.cleaned_data里面 然后保存到数据库 返回啥意义都不大
def admin_add(request):
"""添加管理员"""
title = "新建管理员"
if request.method == "GET":
form = AdminModelForm()
return render(request, 'change.html', {"form": form, "title": title})
form = AdminModelForm(data=request.POST)
if form.is_valid():
print(form.cleaned_data) # form.cleaned_data: 验证通过后所有的数据
form.save()
return redirect('/admin/list/')
return render(request, 'change.html', {"form": form, "title": title})
class AdminModelFormEdit(forms.ModelForm):
class Meta:
model = models.Admin
fields = ["username"]
widgets = {
"username": forms.TextInput(attrs={"class": "form-control"}),
}
def admin_edit(request, nid):
# 对象 / None
row_object = models.Admin.objects.filter(id=nid).first()
msg = "数据不存在哟"
if not row_object:
return render(request, 'error.html', {"msg": msg})
title = "编辑管理员"
if request.method == "GET":
form = AdminModelFormEdit(instance=row_object)
return render(request, 'change.html', {"form": form, "title": title})
form = AdminModelFormEdit(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/admin/list/')
return render(request, 'change.html', {"form": form, "title": title})
def admin_delete(request, nid):
"""删除管理员"""
models.Admin.objects.filter(id=nid).delete()
return redirect('/admin/list/')
class AdminResetModelForm(forms.ModelForm):
confirm_password = forms.CharField(
label="确认密码",
widget=forms.PasswordInput(attrs={"class": "form-control"}),
)
class Meta:
model = models.Admin
fields = ['password', 'confirm_password']
widgets = {
"password": forms.TextInput(attrs={"class": "form-control"})
}
def clean_password(self):
pwd = self.cleaned_data.get("password")
md5_pwd = md5(pwd)
# 去数据库校验当前密码是否与新输入的密码是否一致
exists = models.Admin.objects.filter(id=self.instance.pk, password=md5_pwd).exists()
if exists:
raise ValidationError('不能与以前的密码相同')
return md5_pwd
def clean_confirm_password(self): # 切记当前的方法名可不是谁便乱起的 以clean_开头后面写哪个字段返回值就给哪个字段 值会存储到数据库里
pwd = self.cleaned_data.get("password")
confirm = md5(self.cleaned_data.get("confirm_password")) # 因为上面的密码已经加密了 这里我们也要让确认密码加密 加密的密码与加密的确认密码进行比较
if confirm != pwd:
raise ValidationError("密码不一致")
return confirm # 为什么返回这个值 返回这个值会保存到form.cleaned_data里面 然后保存到数据库 返回啥意义都不大
def admin_reset(request, nid):
"""重置密码"""
# 对象 / None
row_object = models.Admin.objects.filter(id=nid).first()
if not row_object:
return redirect('/admin/list/')
title = "重置密码-{}".format(row_object.username)
if request.method == "GET":
form = AdminResetModelForm(instance=row_object)
return render(request, 'change.html', {"form": form, "title": title})
form = AdminResetModelForm(data=request.POST, instance=row_object)
if form.is_valid():
form.save()
return redirect('/admin/list/')
return render(request, 'change.html', {"form": form, "title": title})
# 登录
class LoginForm(forms.Form):
username = forms.CharField(
label="用户名",
widget=forms.TextInput(attrs={"class": "form-control"})
)
password = forms.CharField(
label="密码",
widget=forms.PasswordInput(attrs={"class": "form-control"}, render_value=True),
required=True, # 是否为必填 默认是true
)
code = forms.CharField(
label="验证码",
widget=forms.TextInput,
required=True,
)
def clean_password(self):
pwd = self.cleaned_data.get("password")
return md5(pwd)
def login(request):
"""登录"""
if request.method == "GET":
form = LoginForm()
return render(request, 'login.html', {"form": form})
form = LoginForm(data=request.POST)
if form.is_valid():
# 验证成功 获取到的用户名和密码
# {'username': '111', 'password': '11'}
# {'username': '111', 'password': '37006769a64a6e8ce0fb4d3c821bb29a'}
# print(form.cleaned_data)
# 验证码的校验
user_input_code = form.cleaned_data.pop('code') # 为什么用pop() 因为数据库中没有验证码这一项先在这剔除掉 为下面的查询用到 pop返回的值时删除的值
code = request.session.get('image_code', "") # 获取session中的验证码
if code.upper() != user_input_code.upper(): # 判断session中的验证码与输入的验证码是否相同
form.add_error("code", "验证码错误") # 不相同给code表单提示出错误信息
return render(request, "login.html", {"form": form})
# 去数据库检验用户名和密码是否正确,获取用户对象, 如果获取不到为None
admin_object = models.Admin.objects.filter(**form.cleaned_data).first()
if not admin_object:
form.add_error("password", "用户名或密码错误") # 如果验证不通过就在password表单下错误提示
return render(request, 'login.html', {"form": form})
# 用户名密码正确
# 网站生成随机字符串;写到用户浏览器的cookie中;再写入session中;
request.session["info"] = {"id": admin_object.id, "name": admin_object.username}
# 登录成功session可以保存七天
request.session.set_expiry(60 * 60 * 24 * 7)
return redirect('/admin/list/')
# return HttpResponse("提交成功")
return render(request, 'login.html', {"form": form})
# 注销
def logout(request):
"""注销"""
request.session.clear()
return redirect('/login/')
def image_code(request):
"""生成图片验证"""
# 调用pillow函数,生成图片
img, code_string = check_code()
# 写入到自己的session中 (以便于后续获取验证码进行校验)
request.session['image_code'] = code_string
# 给session 设置60s超时
request.session.set_expiry(60)
stream = BytesIO() # 创建了一个内存文件
img.save(stream, 'png') # 将img写到这个文件中
return HttpResponse(stream.getvalue()) # 再把这个值从内存中拿出来
@csrf_exempt
def order_list(request):
""""订单"""
# return render(request, "order_list.html")
data_dict = {"status": True, "data": [11, 22, 33, 44]}
print(f"sssss{data_dict}")
return JsonResponse(data_dict)
settings.py
"""
Django settings for day16 project.
Generated by 'django-admin startproject' using Django 4.1.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-v93xy#k)tbr(exa44ejltl)h)gxvg-^kqd@%i@i@v1%ae!^f@c"
# SECURITY WARNING: don't run with debug turned on in production!
# DEBUG = False
# ALLOWED_HOSTS = ['localhost', '127.0.0.1']
DEBUG = True
ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"app01"
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"app01.middleware.auth.AuthMiddleware",
]
ROOT_URLCONF = "day16.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "day16.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.mysql",
"NAME": "gx_day16",
"USER": "root",
"PASSWORD": "",
"HOST": "127.0.0.1",
"PORT": 3306
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
# LANGUAGE_CODE = "en-us" # 英文
LANGUAGE_CODE = "zh-hans" # 中文
TIME_ZONE = "UTC"
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = "/static/"
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"