创建一个django项目 django常用命令 配置及环境:Mac Os + Python3.6.2 一、创建一个Django项目 1.使用虚拟环境 #快速创建虚拟环境 python -m venv prjvenv #激活虚拟环境 source prjvenv/bin/activate 2.创建项目 #安装django pip install django #创建项目 django-admin startproject myblog 3.django设置 myblog/settings.py文件 TIME_ZONE='Asia/Shanghai' 4.数据库迁移 python manage.py migrate 5.启动 python manage.py runserver 二、视图和URL配置 myblog/views.py文件 from django.http import HttpResponse #最简单视图 def hello(request): return HttpResponse("Hello world") #带参数的视图 def hours_ahead(request, offset): try: offset = int(offset) except ValueError: raise Http404() dt = datetime.datetime.now() + datetime.timedelta(hours=offset) html = "In %s hour(s), it will be %s." % (offset, dt) return HttpResponse(html) myblog/urls.py 文件 from django.conf.urls import url from django.contrib import admin from myblog.views import hello from mysite.views import hours_ahead urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^hello/$',hello), url(r'^time/plus/(\d{1,2})/$', hours_ahead), ] 三、使用Django模板 1.模板目录配置 myblog/settings.py文件 TEMPLATES = [ { 'BACKEND': 'django.template.backends.django.DjangoTemplates', 'DIRS': ['app1/templates','app2/templates'...], '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', ], }, }, ] 如果想在项目根目录中放一些主模板(例如在 mysite/templates 目录中),需要像这样设定 DIRS: 'DIRS': [os.path.join(BASE_DIR, 'templates')], 2.视图函数 from django.shortcuts import render import datetime def current_datetime(request): now = datetime.datetime.now() return render(request, 'current_datetime.html', {'current_date': now}) 3.模板文件 myblog/templates/base.html文件 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html lang="en"> <head> <title>{% block title %}{% endblock %}</title> </head> <body> <h1>My helpful timestamp site</h1> {% block content %}{% endblock %} {% block footer %}<hr> <p>Thanks for visiting my site.</p> {% endblock %} </body> </html> 四、模型 1.配置数据库 myblog/setting.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), } } 2.创建应用 python manage.py startapp books 3.激活应用 INSTALLED_APPS = ( ... 'books', ) 4.创建模型 myblogs/books/models.py from django.db import models class Publisher(models.Model): name = models.CharField(max_length=30) address = models.CharField(max_length=50) city = models.CharField(max_length=60) state_province = models.CharField(max_length=30) country = models.CharField(max_length=50) website = models.URLField() def __str__(self): return self.name class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField() def __str__(self): return self.last_name class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE) publication_date = models.DateField() def __str__(self): return self.title 5.迁移数据库 #括号中的内容可以不需要 python manage.py makemigrations (books) python manage.py migrate 6.操作数据 新增数据 # 方式一: p1 = Publisher(...) p1.save() # 方式二: p1 = Publisher.objects.create(...) 更新数据 方式一: p.name = 'Apress Publishing' p.save() 方式二: Publisher.objects.filter(id=52).update(name='Apress') #推荐 查询数据 返回查询集合 Publisher.objects.all() Publisher.objects.filter(name='Apress') #WHERE name = 'Apress'; Publisher.objects.filter(name__contains="press") #WHERE name LIKE '%press%'; 返回单个对象 Publisher.objects.get(name="Apress") #不是1个对象就会报异常 try: p = Publisher.objects.get(name='Apress') #数据库中存在一个数据 except Publisher.DoesNotExist: print ("Apress isn't in the database yet.") #数据库中没有数据 else: print ("Apress is in the database.") #有多个数据 删除 方式一:单个删除 p = Publisher.objects.get(name="O'Reilly") p.delete() 方式二:批量删除 Publisher.objects.filter(country='USA').delete() Publisher.objects.all().delete() 排序 方式一:使用order_by() Publisher.objects.order_by("name", "age") #根据姓名和年龄排序,-name/-age实现反向排序 方式二:在模型内定义 class Publisher(models.Model): ... class Meta: ordering = ['name'] 切片 Publisher.objects.order_by('name')[0:2] 五、后台管理 1.创建管理员用户 python manage.py createsuperuser 2.将模型添加到后台管理 myblog/books/admin.py文件 from django.contrib import admin from .models import Publisher, Author, Book admin.site.register(Publisher) admin.site.register(Author) admin.site.register(Book) 3.修改模型,使字段在后台输入时变为可选项 myblog/books/models.py class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author) publisher = models.ForeignKey(Publisher,on_delete=models.CASCADE) publication_date = models.DateField(blank=True, null=True) 注意:如果想让日期字段(如 DateField、TimeField、DateTimeField)或数值字段(如 IntegerField、DecimalField、FloatField)接受空值,要同时添加 null=True 和 blank=True。 4.通过模型字段的verbose_name值指定后台显示的字段别名 myblog/books/models.py class Author(models.Model): first_name = models.CharField(max_length=30) last_name = models.CharField(max_length=40) email = models.EmailField(blank=True, verbose_name='e-mail') 5.自定义修改后台管理列表 myblog/books/admin.py文件 from django.contrib import admin from .models import Publisher, Author, Book #自定义Author的后台管理列表 class AuthorAdmin(admin.ModelAdmin): list_display = ('first_name', 'last_name', 'email') #定义显示字段 search_fields = ('first_name', 'last_name') #添加字段搜索 #自定义Book的后台管理列表 class BookAdmin(admin.ModelAdmin): list_display = ('title', 'publisher', 'publication_date') #定义显示字段 list_filter = ('publication_date',) #添加时间过滤器 date_hierarchy = 'publication_date' #另一种日期过滤器 ordering = ('-publication_date',) #排序 fields = ('title', 'authors', 'publisher', 'publication_date') #自定义修改表单 filter_horizontal = ('authors',) #使用选项框(多对多关系时使用) raw_id_fields = ('publisher',) #通过id选择对应选项 admin.site.register(Publisher) admin.site.register(Author,AuthorAdmin) admin.site.register(Book,BookAdmin) 六、表单 一、原生表单 1.获取request数据应该try或者设置默认值,防止报错 方式一: def ua_display_good1(request): try: ua = request.META['HTTP_USER_AGENT'] except KeyError: ua = 'unknown' return HttpResponse("Your browser is %s" % ua) 方式二: def ua_display_good2(request): ua = request.META.get('HTTP_USER_AGENT', 'unknown') return HttpResponse("Your browser is %s" % ua) 2.简单的表单提交及表单实例 get和post指向相同的url,根据 if ‘q’ in request.GET:判断是GET还是POST 模板页面 #表单页面:myblog/templates/search_form.html <html> <head> <title>Search</title> </head> <body> {% if errors %} #提示错误信息 <ul> {% for error in errors %} <li>{{ error }}</li> {% endfor %} </ul> {% endif %} <form action="" method="get"> #action为空,表示提交到当前页面 <input type="text" name="q"> <input type="submit" value="Search"> </form> </body> </html> #结果展示页面:myblog/templates/search_results.html <html> <head> <title>Book Search</title> </head> <body> <p>You searched for: <strong>{{ query }}</strong></p> {% if books %} <p>Found {{ books|length }} book{{ books|pluralize }}.</p> <ul> {% for book in books %} <li>{{ book.title }}</li> {% endfor %} </ul> {% else %} <p>No books matched your search criteria.</p> {% endif %} </body> </html> 视图函数:myblog/books/views.py文件 from django.shortcuts import render from django.http import HttpResponse def search(request): errors = [] if 'q' in request.GET: # 如果是post,则存在GET['q'] q = request.GET['q'] if not q: errors.append('Enter a search term.') # 提交了表单,但是内容为空 elif len(q) > 20: # 提交表单,长度超过限制 errors.append('Please enter at most 20 characters.') else: # 正常提交数据 books = Book.objects.filter(title__icontains=q) return render(request, 'search_results.html', {'books': books, 'query': q}) return render(request, 'search_form.html',{'errors': errors}) #不存在GET['q']说明是GET请求 路由:myblog/urls.py文件 urlpatterns = [ ... url(r'^search/$',views.search) ] 二、Django表单模型 1.定义表单类 myblog/books/forms.py from django import forms class ContactForm(forms.Form): subject = forms.CharField(max_length=100) # max_length指定最大长度 email = forms.EmailField(required=False) message = forms.CharField(widget=forms.Textarea) # widget参数,指定表现逻辑,此次指定为文本框 def clean_message(self): # 自定义验表单证器 message = self.cleaned_data['message'] num_words = len(message.split()) if num_words < 4: raise forms.ValidationError("Not enough words!") return message 自定义表单验证器:Django 的表单系统会自动查找名称以 clean_ 开头、以字段名结尾的方法。如果存在这样的方法,在验证过 程中调用。这里,clean_message() 方法会在指定字段的默认验证逻辑(这个 CharField 是必填的)执行完毕 后调用。 2.视图函数 myblog/books/views.py from books.forms import ContactForm def contact(request): if request.method == 'POST': form = ContactForm(request.POST) if form.is_valid(): cd = form.cleaned_data #提示:如果没有配置邮件服务器,调用 send_mail() 时会抛出 ConnectionRefusedError。 send_mail( cd['subject'], cd['message'], cd.get('email', 'noreply@example.com'), ['siteowner@example.com'], ) return HttpResponseRedirect('/contact/thanks/') else: form = ContactForm( initial={'subject': 'I love your site!'} # 可以初始值 ) return render(request, 'contact_form.html', {'form': form}) 3.表单页面 myblogs/templates/contact_form.html 方式一:使用系统默认表单 <html> <head> <title>Contact us</title> </head> <body> <h1>Contact us</h1> {% if form.errors %} <p style="color: red;"> Please correct the error{{ form.errors|pluralize }} below. </p> {% endif %} <form action="" method="post"> {% csrf_token %} <table> {{ form.as_table }} </table> {% csrf_token %} <input type="submit" value="Submit"> </form> </body> </html> 方式二:自定义表单外观样式 <html> <head> <title>Contact us</title> </head> <body> <h1>Contact us</h1> {% if form.errors %} <p style="color: red;"> Please correct the error{{ form.errors|pluralize }} below. </p> {% endif %} <form action="" method="post"> <div class="field"> {{ form.subject.errors }} <label for="id_subject">Subject:</label> {{ form.subject }} </div> <div class="field"> {{ form.email.errors }} <label for="id_email">e-mail:</label> {{ form.email }} </div> <div class="field"> {{ form.message.errors }} <label for="id_message">Message:</label> {{ form.message }} </div> {% csrf_token %} <input type="submit" value="Submit"> </form> </body> </html> 4.路由设置 myblogs/myblogs/urls.py urlpatterns = [ ... url(r'^contact/$', views.contact), ] django常用命令