django基础之简单使用
当前python版本3.10.8 django版本4.1.3
准备开始
# 安装
pip install django
# 查看django版本
py -m django --version
# 新建项目
mkdir demo
django-admin startproject mysite demo
#生成mysite目录结构
# demo/mysite目录
# __init__.py
# asgi.py
# settings.py
# urls.py
# wsgi.py
# manage.py
# 启动
py manage.py runserver 8000 #打开浏览器访问127.0.0.1:8000
manage.py
: 管理 Django 项目的命令行工具。
mysite/__init__.py
:一个空文件,告诉 Python 这个目录应该被认为是一个 Python 包。
mysite/settings.py
:Django 项目的配置文件。
mysite/urls.py
:Django 项目的 URL 声明,就像网站的“目录”。
mysite/asgi.py
:项目运行在 ASGI 兼容的 Web 服务器上的入口。
mysite/wsgi.py
:项目运行在 WSGI 兼容的Web服务器上的入口。
新增url
# mysite目录下新建views.py
from django.shortcuts import render,HttpResponse
def hello(req):
return HttpResponse("hello world!")
# mysite/urls.py
from django.contrib import admin
from django.urls import path
from . import views
urlpatterns = [
path('hello/', views.hello),
]
增加应用
py manage.py startapp post
# 生成 mysite/post目录和目录下 admin.py apps.py models.py tests.py views.py __init__.py
# mysite/setting.py中INSTALLED_APPS增加 post
INSTALLED_APPS = [
...
'post'
]
# post/views.py
from django.shortcuts import render,HttpResponse
def index(request):
return HttpResponse('post/index')
# 创建post/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('index', views.index,name="index"),
]
# mysite/urls.py
urlpatterns = [
...
path('post/', include('post.urls')),
]
创建模型
Django将关系型的表(table)转换成为一个类(class)。而每个记录(record)是该类下的一个对象(object)。我们可以使用基于对象的方法,来操纵关系型的数据库。
# post/models.py
from django.db import models
class Post(models.Model):
"""post"""
title=models.CharField(max_length=50)
content=models.CharField(max_length=500)
create_at=models.DateTimeField(auto_now_add=True)
def __str__(self):
"""返回模型的字符串表示"""
return self.title
# 根据模型生成迁移
py manage.py makemigrations
# 将迁移更新到DB
py manage.py migrate post
# post/views.py添加
from post.models import Post
def lists(request):
post_list = Post.objects.all()
post_str = map(str, post_list)
return HttpResponse("<p>" + ' '.join(post_str) + "</p>")
def create(request):
post=Post(title='bb',content='bbbbbbb')
post.save()
return HttpResponse("<p>created bb </p>")
# post/urls.py添加
urlpatterns = [
...
path('lists',views.lists,name="lists"),
path('create',views.create,name="create"),
]
引入模板
# mysite/setting.py增加配置
TEMPLATES =[
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR,'templates')],
'APP_DIRS': True, #允许每个app使用自己的templates目录
'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',
],
},
},
]
# post/views.py 中lists修改为
def lists(request):
post_list = Post.objects.all()
post_str = map(str, post_list)
return render(request,'post/lists.html',{'str':' '.join(post_str),'num':len(post_list) })
# demo目录下创建templates目录,templates下创建post目录/lists.html
<p>I am out post lists {{str}}</p>
<p>nums :{{num}}</p>
# post目录下创建templates/post/lists.html
# Django按照INSTALLED_APPS中的添加顺序查找Templates,不同的app下templates目录中的同名XX.html会造成冲突
<p>I am inner post lists {{str}}</p>
<p>nums :{{num}}</p>
# 访问http://127.0.0.1:8000/post/lists
I am out post lists aa bb
nums :2
# 删除demo/templates/post/lists.html文件,访问http://127.0.0.1:8000/post/lists
I am inner post lists aa bb
nums :2
加入模板语法
# post/views.py 中lists修改为
def lists(request):
post_list = Post.objects.all()
return render(request,'post/lists.html',{'lists':post_list})
# 创建demo/templates/post/lists.html文件
{% if lists %} {% for item in lists %} {% if forloop.first %}
<div style="color: red">
<p>id: {{item.id}}</p>
<p>title:{{item.title}}</p>
<p>content:{{item.content}}</p>
<p>created_at:{{item.created_at}}</p>
</div>
{% elif forloop.last %}
<div style="color: blue">
<p>id: {{item.id}}</p>
<p>title:{{item.title}}</p>
<p>content:{{item.content}}</p>
<p>created_at:{{item.created_at}}</p>
</div>
{% else %}
<div style="color: green">
<p>id: {{item.id}}</p>
<p>title:{{item.title}}</p>
<p>content:{{item.content}}</p>
<p>created_at:{{item.created_at}}</p>
</div>
{% endif %} {% endfor %}
<p>nums :{{lists|length}}</p>
<p>{{ value|default:'nothing' }}</p>
{% else %} No data {% endif %}
静态文件
# demo/mysite/settings.py 配置静态文件存放位置
STATIC_URL = 'static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
# 创建demo/static目录,放入plugins/bootstrap-5.1.3-dist 包,创建demo/templates/layout.html文件
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="{% static 'plugins/bootstrap-5.1.3-dist/css/bootstrap.min.css' %}" />
<script type="text/javascript" src="{% static 'plugins/bootstrap-5.1.3-dist/js/bootstrap.bundle.min.js' %}"></script>
<title>Document</title>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="#">Navbar</a>
<div class="collapse navbar-collapse">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link active" aria-current="page" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
</ul>
</div>
</div>
</nav>
<div class="container-fluid mt-3">
{% block mainbody %}
<p>welecome</p>
{% endblock %}
</div>
</body>
</html>
# 修改demo/templates/post/lists.html,模板继承自layout.html
{% extends "layout.html" %} {% block mainbody %} {% if lists %}
<div class="row">
{% for item in lists %}
<div class="col-3">
<div class="card">
<div class="card-header">{{item.id}}</div>
<div class="card-body">
<h5 class="card-title">{{item.title}}</h5>
<p class="card-text">{{item.content}}</p>
</div>
</div>
</div>
{% endfor %}
</div>
{% else %}
<div class="alert alert-danger" role="alert">No data</div>
{% endif %} {% endblock %}
form和保存数据
# 创建demo/templates/post/create.html
{% extends "layout.html" %} {% block mainbody %}
<div class="row">
<div class="col-6">
<div class="card">
<div class="card-header">create</div>
<form action="/post/create" method="post">
{% csrf_token %}
<div class="card-body">
<div class="input-group mb-3">
<span class="input-group-text">title</span>
<input type="text" class="form-control" name="title" />
</div>
<div class="input-group mb-3">
<span class="input-group-text">content</span>
<textarea class="form-control" name="content"></textarea>
</div>
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
{% if p %}
<div class="col-6">
<div class="card">
<div class="card-header">{{p.id}}</div>
<div class="card-body">
<h5 class="card-title">{{p.title}}</h5>
<p class="card-text">{{p.content}}</p>
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}
# demo/post/views.py增加
def create(request):
if request.POST:
title = request.POST['title']
content=request.POST['content']
p=Post(title=title,content=content)
p.save()
return render(request,'post/create.html',{'p':p})
return render(request,'post/create.html')
加入表单数据验证
# demo/post/views.py
def create(request):
if request.POST:
form = PostForm(request.POST)
if form.is_valid():
title = form.cleaned_data['title']
content=form.cleaned_data['content']
p=Post(title=title,content=content)
p.save()
return render(request,'post/create.html',{'p':p})
else:
return render(request,'post/create.html',{'errors':form.errors})
return render(request,'post/create.html')
# demo/templates/post/create.html
{% extends "layout.html" %} {% block mainbody %}
<div class="row">
<div class="col-6">
<div class="card">
<div class="card-header">create</div>
<form action="/post/create" method="post">
{% csrf_token %}
<div class="card-body">
<div class="input-group mb-3">
<span class="input-group-text">title</span>
<input type="text" class="form-control" name="title" />
</div>
<div class="input-group mb-3">
<span class="input-group-text">content</span>
<textarea class="form-control" name="content"></textarea>
</div>
{% if errors %}
<div class="alert alert-warning" role="alert">{% for item in errors.values %} {{item}} {% endfor %}</div>
{% endif %}
</div>
<div class="card-footer">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</form>
</div>
</div>
{% if p %}
<div class="col-6">
<div class="card">
<div class="card-header">{{p.id}}</div>
<div class="card-body">
<h5 class="card-title">{{p.title}}</h5>
<p class="card-text">{{p.content}}</p>
</div>
</div>
</div>
{% endif %}
</div>
{% endblock %}
使用django admin强大的管理功能
# demo/post/models.py增加
class Contact(models.Model):
name = models.CharField(max_length=200)
age = models.IntegerField(default=0)
email = models.EmailField()
def __str__(self):
return self.name
class Tag(models.Model):
contact = models.ForeignKey(Contact, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
def __str__(self):
return self.name
# 迁移
py manage.py makemigrations
py manage.py migrate
# 创建superuser
py manage.py createsuperuser
# demo/post/admin.py增加
from post.models import Post,Contact,Tag
class TagInline(admin.TabularInline):
model = Tag
class ContactAdmin(admin.ModelAdmin):
list_display = ('name','age', 'email')
inlines = [TagInline]
search_fields = ('name','email')
#fields = ('name', 'email')
fieldsets = (
['Main',{
'fields':('name','email'),
}],
['Advance',{
'classes': ('collapse',), # CSS
'fields': ('age',),
}]
)
admin.site.register(Contact, ContactAdmin)
admin.site.register([Post,Tag])
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix