Django学习笔记

Django学习笔记

  最近在学习一些WEB相关知识,这篇博文用于记录一些知识点,基于Django2.2来编写。

初始化

新建虚拟环境

  安装virtualenv:

1
pip install virtualenv

  virtualenv使用:

1
2
3
4
5
6
# 创建
virtualenv <虚拟环境名称>
# 启动
activate
# 退出
deactiavte

一键导出/安装扩展

  命令提示符下:

1
2
pip freeze > requirements.txt
pip install -r requirements.txt

基础知识

新建项目

  CMD下输入:django-admin startproject <项目名>

初始化数据库

  CMD下输入:python manage.py migrate

启动本地项目

  CMD下输入:python manage.py runserver

创建管理员

  CMD下输入:python manage.py createsuperuser

创建应用

  CMD下输入:python manage.py startapp <应用名>

  在app目录下定义models.py,例如:

1
2
3
class Article(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()

  保存后在项目目录下,settings.py注册该应用:

  CMD下执行:

basic
1
2
python manage.py makemigrations
python manage.py migrate

  在应用目录下,编辑admin.py:

1
2
from .models import Article
admin.site.register(Article)

绑定url

  在项目目录下,编辑urls.py,参考注释:

1
2
Add an import:  from my_app import views
Add a URL to urlpatterns: path('', views.home, name='home')

注意事项

  公用全局设置可放在settings中,统一管理

1
2
from django.conf import settings
settings.XXX

进阶知识

定制admin后台

  在应用目录下,models.py中的类中,增加__str__方法,例如:

1
2
3
4
5
6
7
8
9
from django.db import models

# Create your models here.
class Article(models.Model):
title = models.CharField(max_length=30)
content = models.TextField()

def __str__(self):
return "<Article: %s>" % self.title

  项目目录下的admin.py:

1
2
3
4
5
6
7
8
9
10
11
from django.contrib import admin
from .models import Article

# Register your models here.
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ('id','title','content')
ordering = ('id',)
# 倒序:('-id',)

# admin.site.register(Article, ArticleAdmin)

修改模型

  模型修改后要重新执行

1
2
python manage.py makemigrations
python manage.py migrate

增加其他参数

  修改models.py,增加如下内容:

1
2
3
4
5
6
7
from django.utils import timezone

class Article(models.Model):
......
created_time = models.DateTimeField(auto_now_add=True)
last_updated_time = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.DO_NOTHING,default=1)

  相应的应于admin中的list_display增加字段。

  给类增加默认排序,在父类中增加子类,形如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
from django.db import models
from django.contrib.auth.models import User

class BlogType(models.Model):
type_name = models.CharField(max_length=15)

def __str__(self):
return self.type_name

class Blog(models.Model):
title = models.CharField(max_length=50)
blog_type = models.ForeignKey(BlogType,on_delete=models.DO_NOTHING)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.DO_NOTHING)
created_time = models.DateTimeField(auto_now_add=True)
last_updated_time = models.DateTimeField(auto_now=True)

def __str__(self):
return "<Blog: %s>" % self.title

class Meta:
ordering = ['-created_time']

使用Shell命令

  命令提示符下输入:

1
python manage.py shell

管理博文

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
>>>from blog.models import Blog
>>>from blog.models import BlogType
>>>from django.contrib.auth.models import User
# 常用
>>>Blog.objects.all()
>>>BlogType.objects.all()
>>>User.objects.all()
# 实例化
>>>blog = Blog()
>>>blog.title = 'shell下第1篇'
>>>blog.content = 'xxxxxxxxxxxxxxx'
>>>blog_type = BlogType.objects.all()[0]
>>>blog.blog_type = blog_type
>>>user = User.objects.all()[0]
>>>blog.author = user
# 保存
>>>blog.save()
#批量添加
>>>for i in range(1,31):
... blog = Blog()
... blog.title = "for %s" % i
... blog.content = 'xxxx:%s' % i
... blog.blog_type = blog_type
... blog.author = user
... blog.save()

网页搭建

使用模版

  应用目录下创建文件夹templates,然后创建html文件,编辑view.py,类似以下编辑:

1
2
3
4
5
6
7
8
9
10
11
from django.shortcuts import render
from article.models import Article

def article_detail(request, article_id):
try:
article = Article.objects.get(id=article_id)
context = {}
context['article_obj'] = article
return render(request, "article_detail.html", context)
except Article.DoesNotExist:
raise Http404('不存在')

  也可以使用render_to_response方法:

1
2
3
from django.shortcuts import render_to_response
......
return render_to_response("article_detail.html", context)

  还有get_object_or_404方法:

1
2
3
4
5
6
7
8
from django.shortcuts import render_to_response,get_object_or_404
from article.models import Article

def article_detail(request, article_id):
article = get_object_or_404(Article, pk=article_id)
context = {}
context['article_obj'] = article
return render_to_response("article_detail.html", context)

  html文件类似:

1
2
3
4
5
6
7
8
9
<html>
<head>
<body>
<h2>{{ article_obj.title }}</h2>
<hr>
<p>{{ article_obj.content }}</p>
</body>
</head>
</html>

创建目录

  创建目录html页面,在urls里绑定,使用循环来遍历文章id,使用pk而不是id是更保险的写法。

1
2
3
4
5
6
7
8
9
<html>
<head>
<body>
{% for article in articles %}
<a href="/article/{{ article.pk }}">{{ article.title }}</a>
{% endfor %}
</body>
</head>
</html>

  超链接部分也可以用这种写法:

1
<a href="{% url 'article_detail' article.pk %}">{{ article.title }}</a>

url合并

  如果有很多应用,按之前的写法,url会太臃肿,因此可以在应用下新建urls.py:

1
2
3
4
5
6
7
from django.urls import path
from . import views

urlpatterns = [
path('<int:article_id>', views.article_detail, name='article_detail'),
path('', views.article_list, name='article_list'),
]

  相应的,项目下url可改为:

1
2
3
4
5
6
7
8
9
from django.contrib import admin
from django.urls import include,path
from . import views

urlpatterns = [
path('admin/', admin.site.urls),
path('',views.index),
path('article/',include('article.urls')),
]

使用html模版

  为了减少重复html代码的使用,可以使用block块来标记可替代内容,首先在项目根目录下创建templates文件夹,创建base.html并写入以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<!-- {% block <别名>%}{% endblock %} -->
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="UTF-8">
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<div>
<a href="{% url 'home' %}"><h3>个人博客网站</h3></a>
</div>
<hr>
{% block content %}{% endblock %}
</body>
</html>

  与之相应地,可以在其他的html文件中,省略这些内容,只需要用extends引用,再到block块中填充即可,例如blog_list.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!-- {% extends 'base.html' %} -->
<!-- {% block <别名>%}{% endblock %} -->
{% extends 'base.html' %}

{# 页面标题 #}
{% block title %}
我的网站
{% endblock %}

{# 页面内容 #}
{% block content %}
{% for blog in blogs %}
<a href="{% url 'blog_detail' blog.pk%}">
<h3>{{ blog.title }}</h3>
</a>
<p>{{ blog.content|truncatechars:30 }}</p>
{% empty %}
<p>-- 暂无博客,敬请期待 --</p>
{% endfor %}
<p>一共有{{ blogs|length}}篇文章</p>
{% endblock %}

  然后在项目文件夹中的setting.py中编辑TEMPLATES的DIRS列表,加入os.path.join(BASE_DIR, 'templates')

使用css

  在项目目录下新建static文件夹,写入base.css文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
* {
margin: 0;
padding: 0;
}
div.nav {
background-color: #eee;
border-bottom: 1px solid #ccc;
padding: 10px 5px
}
div.nav a{
text-decoration: none;
color:black;
padding: 5px 10px;
}
div.nav a.logo {
display: inline-block;
font-size: 120%;
}

  然后在项目文件夹中的setting.py中加入:

1
2
3
STATICFILES_DIRS = [
os.path.join(BASE_DIR, 'static'),
]

  引用方法:

1
2
3
4
5
6
7
<!-- head中写入 -->
<link rel="stylesheet" href="/static/base.css">

<!-- 也可以用django自带方法,在html顶部写入 -->
{% load staticfiles %}
<!-- 再到head中写入 -->
<link rel="stylesheet" href="{% static 'base.css'%}">

使用css框架Bootstrap

基础

  访问官网,下载新版Bootstrap,保留以下文件,放在项目static的新建的Bootstrap文件夹中:

1
2
3
4
5
6
7
css
bootstrap.min.css
bootstrap.min.css.map
font
all
js
bootstrap.min.js

  参考文档,如果需要导入,可按如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{% load staticfiles %}
<!DOCTYPE html>
<html lang="zh-cn">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{% block title %}{% endblock %}</title>
<link rel="stylesheet" href="{% static 'base.css' %}">
<link rel="stylesheet" href="{% static 'bootstrap-3.3.7/css/bootstrap.min.css' %}">
<script type="text/javascript" src="{% static 'jquery-1.12.4.min.js' %}"></script>
<script type="text/javascript" src="{% static 'bootstrap-3.3.7/js/bootstrap.min.js' %}"></script>
{% block header_extends %}
<!-- 此处可以被其他html文件继承,用于加载css文件 -->
{% endblock %}
</head>
<body>
</body>
</html>

栅格系统

  类前缀从超小到大分别为.col-xs-、.col-sm-、.col-md-、.col-lg-,也可以使用类如.visible-xs-block、.hidden-xs来显示或者隐藏,使用 例如.col-md-offset- 1类可以将列向右侧偏移。

1
2
3
4
<div class="row">
<div class="col-md-8">.col-md-8</div>
<div class="col-md-4">.col-md-4</div>
</div>

分页

基础

  shell中可以大致了解分页器的功能:

1
2
3
4
5
6
7
8
9
10
11
>>>from django.core.paginator import Paginator
>>>from blog.models import Blog
>>>blogs = Blog.objects.all()
>>>paginator = Paginator(blogs, 10)
# 常用
>>>paginator.count
>>>paginator.num_pages
>>>paginator.page_range
# 赋值
>>>page1 = paginator.page(1)
>>>page1.object_list

  修改views.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
def blog_list(request):
blogs_all_list = Blog.objects.all()
paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER) # 每10篇为1页
page_num = request.GET.get("page", 1) # 获取url页码参数(GET请求)
page_of_blogs = paginator.get_page(page_num)
current_page_num = page_of_blogs.number #获取当前页码
# 获取当前页码前后各两位的范围
# page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \
# list(range(current_page_num, min(current_page_num + 2, paginator.num_pages) + 1))
page_range = [x for x in range(current_page_num-2, current_page_num+3) if (x>0 and x<paginator.num_pages + 1)]
# 加上首页和尾页以及省略页码标记
if page_range[0] - 1 >= 2:
page_range.insert(0,'...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append('...')
if page_range[0] != 1:
page_range.insert(0,1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
context = {}
context['blogs'] = page_of_blogs.object_list
context['page_of_blogs'] = page_of_blogs
context['page_range'] = page_range
context['blog_types'] = BlogType.objects.all()
# context['blogs_count'] = Blog.objects.all().count()
return render_to_response('blog/blog_list.html',context)

def blogs_with_type(request, blog_type_pk):
blog_type = get_object_or_404(BlogType, pk=blog_type_pk)
blogs_all_list = Blog.objects.filter(blog_type=blog_type)
paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER) # 每10篇为1页
page_num = request.GET.get("page", 1) # 获取url页码参数(GET请求)
page_of_blogs = paginator.get_page(page_num)
current_page_num = page_of_blogs.number #获取当前页码
# 获取当前页码前后各两位的范围
# page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \
# list(range(current_page_num, min(current_page_num + 2, paginator.num_pages) + 1))
page_range = [x for x in range(current_page_num-2, current_page_num+3) if (x>0 and x<paginator.num_pages + 1)]
# 加上首页和尾页以及省略页码标记
if page_range[0] - 1 >= 2:
page_range.insert(0,'...')
if paginator.num_pages - page_range[-1] >= 2:
page_range.append('...')
if page_range[0] != 1:
page_range.insert(0,1)
if page_range[-1] != paginator.num_pages:
page_range.append(paginator.num_pages)
context = {}
context['blog_type'] = blog_type
context['blogs'] = page_of_blogs.object_list
context['page_of_blogs'] = page_of_blogs
context['page_range'] = page_range
context['blog_types'] = BlogType.objects.all()
# context['blogs_count'] = Blog.objects.all().count()
return render_to_response('blog/blogs_with_type.html',context)

  修改blog_list.html:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<div class="paginator">
<ul class="pagination">
<!-- 上一页 -->
<li>
{% if page_of_blogs.has_previous %}
<a href="?page={{ page_of_blogs.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">&laquo;</span>
</a>
{% else %}
<span aria-hidden="true">&laquo;</span>
{% endif %}
</li>
<!-- 全部页码 -->
{% for page_num in page_range %}
{% if page_num == page_of_blogs.number %}
<li class='active'><span>{{ page_num }}</span></li>
<!-- <li class='active'><a href="?page={{ page_num }}">{{ page_num }}</a></li> -->
{% else %}
{% if page_num == '...' %}
<li><span>{{ page_num }}</span></li>
{% else %}
<li><a href="?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endif %}
{% endfor %}
<!-- 下一页 -->
<li>
{% if page_of_blogs.has_next %}
<a href="?page={{ page_of_blogs.next_page_number }}" aria-label="Next">
<span aria-hidden="true">&raquo;</span>
</a>
{% else %}
<span aria-hidden="true">&raquo;</span>
{% endif %}
</li>
</ul>
<p>
共有{{ page_of_blogs.paginator.count}}篇博客,
当前第{{ page_of_blogs.number }}页,共{{ page_of_blogs.paginator.num_pages }}页
</p>
</div>

上一页/下一页

  编辑views.py,其中__gt表示大于,同理lt为小于:

1
2
3
4
5
6
7
def blog_detail(request,blog_pk):
context = {}
blog = get_object_or_404(Blog, pk=blog_pk)
context['next_blog'] = Blog.objects.filter(created_time__gt=blog.created_time).last()
context['previous_blog'] = Blog.objects.filter(created_time__lt=blog.created_time).first()
context['blog'] = blog
return render_to_response('blog/blog_detail.html',context)

评论

3D cell culture 3D cell culturing 3D cell microarrays 3D culture 3D culture model 3D printing 3D spheroid 3D tumor culture 3D tumors 3D vascular mapping ACT ADV AUTODESK Abdominal wall defects Acoustofluidics Adipocyte Adipogenesis Adoptive cell therapy AirPods Alginate Anticancer Anticancer agents Anticancer drugs Apple Apriori Association Analysis August AutoCAD Autodock Vina Bio-inspired systems Biochannels Bioengineering Bioinspired Biological physics Biomarkers Biomaterial Biomaterials Biomimetic materials Biomimetics Bioprinting Blood purification Blood-brain barrier Bone regeneration Breast cancer Breast cancer cells Breast neoplasms CM1860 CRISPR/Cas9 system CSS CTC isolation CTCs Cancer Cancer angiogenesis Cancer cell invasion Cancer immunity Cancer immunotherapy Cancer metabolism Cancer metastasis Cancer models Cancer screening Cancer stem cells Cell adhesion Cell arrays Cell assembly Cell clusters Cell culture Cell culture techniques Cell mechanical stimulation Cell morphology Cell trapping Cell-bead pairing Cell-cell interaction Cell-laden gelatin methacrylate Cellular uptake Cell−cell interaction Cervical cancer Cheminformatics Chemotherapy Chimeric antigen receptor-T cells Chip interface Circulating tumor cells Clinical diagnostics Cmder Co-culture Coculture Colon Colorectal cancer Combinatorial drug screening Combinatorial drug testing Compartmentalized devices Confined migration Continuous flow Convolutional neural network Cooking Crawler Cryostat Curved geometry Cytokine detection Cytometry Cytotoxicity Cytotoxicity assay DESeq DNA tensioners Data Mining Deep learning Deformability Delaunay triangulation Detective story Diabetic wound healing Diagnostics Dielectrophoresis Differentiation Digital microfluidics Direct reprogramming Discrimination of heterogenic CTCs Django Double emulsion microfluidics Droplet Droplet microfluidics Droplets generation Droplet‐based microfluidics Drug combination Drug efficacy evaluation Drug evaluation Drug metabolism Drug resistance Drug resistance screening Drug screening Drug testing Dual isolation and profiling Dynamic culture Earphone Efficiency Efficiency of encapsulation Elastomers Embedded 3D bioprinting Encapsulation Endothelial cell Endothelial cells English Environmental hazard assessment Epithelial–mesenchymal transition Euclidean distance Exosome biogenesis Exosomes Experiment Extracellular vesicles FC40 FP-growth Fabrication Fast prototyping Fibroblasts Fibrous strands Fiddler Flask Flow rates Fluorescence‐activated cell sorting Functional drug testing GEO Galgame Game Gene Expression Profiling Gene delivery Gene expression profiling Gene targetic Genetic association Gene‐editing Gigabyte Glypican-1 GoldenDict Google Translate Gradient generator Growth factor G‐CSF HBEXO-Chip HTML Hanging drop Head and neck cancer Hectorite nanoclay Hepatic models Hepatocytes Heterotypic tumor HiPSCs High throughput analyses High-throughput High-throughput drug screening High-throughput screening assays High‐throughput methods Histopathology Human neural stem cells Human skin equivalent Hydrogel Hydrogel hypoxia Hydrogels ImageJ Immune checkpoint blockade Immune-cell infiltration Immunoassay Immunological surveillance Immunotherapy In vitro tests In vivo mimicking Induced hepatocytes Innervation Insulin resistance Insulin signaling Interferon‐gamma Intestinal stem cells Intracellular delivery Intratumoral heterogeneity JRPG Jaccard coefficient JavaScript July June KNN Kidney-on-a-chip Lab-on-a-chip Laptop Large scale Lattice resoning Leica Leukapheresis Link Lipid metabolism Liquid biopsy Literature Liver Liver microenvironment Liver spheroid Luminal mechanics Lung cells MOE Machine Learning Machine learning Macro Macromolecule delivery Macroporous microgel scaffolds Magnetic field Magnetic sorting Malignant potential Mammary tumor organoids Manhattan distance Manual Materials science May Mechanical forces Melanoma Mesenchymal stem cells Mesoporous silica particles (MSNs) Metastasis Microassembly Microcapsule Microcontact printing Microdroplets Microenvironment Microfluidic array Microfluidic chips Microfluidic device Microfluidic droplet Microfluidic organ-on-a chip Microfluidic organ-on-a-chip Microfluidic patterning Microfluidic screening Microfluidic tumor models Microfluidic-blow-spinning Microfluidics Microneedles Micropatterning Microtexture Microvascular Microvascular networks Microvasculatures Microwells Mini-guts Mirco-droplets Molecular docking Molecular imprinting Monolith Monthly Multi-Size 3D tumors Multi-organoid-on-chip Multicellular spheroids Multicellular systems Multicellular tumor aggregates Multi‐step cascade reactions Myeloid-derived suppressor cells NK cell NanoZoomer Nanomaterials Nanoparticle delivery Nanoparticle drug delivery Nanoparticles Nanowell Natural killer cells Neural progenitor cell Neuroblastoma Neuronal cell Neurons Nintendo Nissl body Node.js On-Chip orthogonal Analysis OpenBabel Organ-on-a-chip Organ-on-a-chip devices Organically modified ceramics Organoids Organ‐on‐a‐chip Osteochondral interface Oxygen control Oxygen gradients Oxygen microenvironments PDA-modified lung scaffolds PDMS PTX‐loaded liposomes Pain relief Pancreatic cancer Pancreatic ductal adenocarcinoma Pancreatic islet Pathology Patient-derived organoid Patient-derived tumor model Patterning Pearl powder Pearson coefficient Penetralium Perfusable Personalized medicine Photocytotoxicity Photodynamic therapy (PDT) Physiological geometry Pluronic F127 Pneumatic valve Poetry Polymer giant unilamellar vesicles Polystyrene PowerShell Precision medicine Preclinical models Premetastatic niche Primary cell transfection Printing Protein patterning Protein secretion Pubmed PyMOL Pybel Pytesseract Python Quasi-static hydrodynamic capture R RDKit RNAi nanomedicine RPG Reactive oxygen species Reagents preparation Resistance Review Rod-shaped microgels STRING Selective isolation Self-assembly Self-healing hydrogel September Signal transduction Silk-collagen biomaterial composite Similarity Single cell Single cells Single molecule Single-cell Single-cell RNA sequencing Single‐cell analysis Single‐cell printing Size exclusion Skin regeneration Soft lithography Softstar Spheroids Spheroids-on-chips Staining StarBase Stem cells Sub-Poisson distribution Supramolecular chemistry Surface chemistry Surface modification Switch T cell function TCGA Tanimoto coefficient The Millennium Destiny The Wind Road Thin gel Tissue engineering Transcriptome Transfection Transient receptor potential channel modulators Tropism Tubulogenesis Tumor environmental Tumor exosomes Tumor growth and invasion Tumor immunotherapy Tumor metastasis Tumor microenvironment Tumor response Tumor sizes Tumor spheroid Tumor-on-a-chip Tumorsphere Tumors‐on‐a‐chip Type 2 diabetes mellitus Ultrasensitive detection Unboxing Underlying mechanism Vascularization Vascularized model Vasculature Visual novel Wettability Windows Terminal Word Writing Wuxia Xenoblade Chronicles Xin dynasty XuanYuan Sword Youdao cnpm fsevents miR-125b-5p miR-214-3p miRNA signature miRanda npm
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×