好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

如何快速搭建Django项目

一、创建一个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>
<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)原生表单

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)
]

(2)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测试数据'),
????????????????['siteowner@example测试数据'],
????????????????)
????????????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>
????????????{{?form.subject.errors?}}
????????????<label?for="id_subject">Subject:</label>
????????????{{?form.subject?}}
????????</div>
????????<div>
????????????{{?form.email.errors?}}
????????????<label?for="id_email">e-mail:</label>
????????????{{?form.email?}}
????????</div>
????????<div>
????????????{{?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项目的详细内容...

  阅读:54次