django从零开始
当前python版本3.10.8 django版本4.1.3
#开始步骤
pip install django django-admin startproject mysite #生成mysite目录 mysite/mysite目录 __init__.py asgi.py settings.py urls.py wsgi.py manage.py python manage.py runserver 8000 打开浏览器访问127.0.0.1:8000
# 新增url
#urls.py from django.contrib import admin from django.urls import path from . import views urlpatterns = [ path('admin/', admin.site.urls), path('hello/', views.hello), ] #mysite目录下新建views.py from django.shortcuts import render,HttpResponse def hello(req): return HttpResponse("hello world!")
#增加app
python 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 #命令行执行迁移 python manage.py makemigrations python 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) }) #mysite根目录下创建templates目录(与post目录平级),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 #删除mysite/templates/post/lists.html文件,(python manage.py runserver 8000) 访问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}) #创建/mysite/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 %}
#静态文件
#mysite/mysite/settings.py STATIC_URL = 'static/' STATICFILES_DIRS = ( os.path.join(BASE_DIR, 'static'), ) #创建mysite/static目录,放入plugins/bootstrap-5.1.3-dist 包,创建mysite/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> #修改mysite/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和保存数据
#创建mysite/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 %} #mysite/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') #mysite/post/urls.py增加 path('create',views.create,name="create")
#加入表单数据验证
#mysite/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') #mysite/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强大的管理功能
#mysite/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 #migrate python manage.py makemigrations python manage.py migrate #superuser python manage.py createsuperuser #mysite/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])