昨天大概搞了一下Django开发环境,今天尝试在本地把一个博客简单的搭建起来
今天了解到所谓env,虚拟环境是不必要的,虚拟环境只是为了保证不受其他因素的干扰,直接在原有基础上搞。
1.创建一个项目:django-admin startproject Tk_blog
#项目结构1
tyrant@ubuntu:~/Desktop/Django/Tk_blog$ tree
.
Tk_blog
│ db.sqlite3
│ manage.py
│
└─Tk_blog
│ settings.py
│ urls.py
│ wsgi.py
└─ __init__.py
#像昨天一样修改settings.py里的ALLOWED_HOSTS = ['*'],见上一篇Django初探
django自带服务器打开:python3 manage.py runserver 0.0.0.0:8000
访问本地8000端口
2.创建app:
python3 manage.py startapp article
#项目结构2
tyrant@ubuntu:~/Desktop/Django/Tk_blog$ tree
.
├── article
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── manage.py
└── Tk_blog
├── asgi.py
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-37.pyc
│ ├── settings.cpython-37.pyc
│ ├── urls.cpython-37.pyc
│ └── wsgi.cpython-37.pyc
├── settings.py
├── urls.py
└── wsgi.py
3.注册app:Tk_blog/settings.py的INSTALLED_APP
模块修改
#Tk_blog/settings.py的INSTALLED_APP模块修改后
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'article',
]
4.配置访问路径:Tk_blog/urls.py修改
#/Tk_blog/urls.py修改
from django.contrib import admin
from django.urls import path,include
urlpatterns = [
path('admin/', admin.site.urls),
path('article/', include('article.urls', namespace='article')),
]
path为Django的路由语法:
1.参数article/分配了app的访问路径
2.include将路径分发给下一步处理
3.namespace可以保证反查到唯一的url,即使不同的app使用相同的url(后面会用到)
在我的理解就是写了位置,就要有这么一个地方,有来有往,所以要创建article/urls.py
文件
#创建修改article/urls.py
from django.urls import path
from . import views
app_name = 'article'
urlpatterns = [
#path('article-list/', views.article_list, name='article_list'),# 目前还没有urls,前面为小插曲测试使用
]
5.编写article/Model.py
#article/Model.py修改
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
# Create your models here.
class ArticlePost(models.Model):
author = models.ForeignKey(User,on_delete=models.CASCADE)
title = models.CharField(max_length=100)
body = models.TextField()
created = models.DateTimeField(default=timezone.now)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-created',)
def __str__(self):
return self.title
6.数据迁移(Migrations)
感觉说的太难懂了,个人感觉就是搞定数据库,了解详情可以查看参考链接,毕竟大佬写的比我详细的多
不进行这个操作会导致后面如下问题
Q1:创建用户时,django.db.utils.OperationalError: no such table: auth_user
每当修改了models.py文件,都需要用makemigrations和migrate这两条指令迁移数据
小插曲:搞一下view视图测试
article/view.py的修改
#article/view.py修改
from django.shortcuts import render
from django.http import HttpResponse
# Create your views here.
def article_list(request):
return HttpResponse('Hello!')
修改article/urls.py,其实之前那个图,就是这个,不过代码块注释掉了,原谅我懒...
#修改article/urls.py
from django.urls import path
from . import views
app_name = 'article'
urlpatterns = [
path('article-list/', views.article_list, name='article_list'),# 目前还没有urls
]
启动django服务器python3 manage.py runserver 0.0.0.0:8000
,并访问本地8000端口的article/article-list/
小插曲view测试结束
7.创建管理员用户:python3 manage.py createsuperuser
按照提示输入对应内容
8.注册到后台
修改article/admin.py文件
此时记得django服务器记得打开:
python3 manage.py runserver 0.0.0.0:8000
,访问本地8000端口admin/,如图输入之前设置的用户名密码就可登录
其实就可以添加文章了,解决了写的问题
安装sqlite3管理查看数据库:sudo apt install sqlite3
9.改变试图函数
之前有个hello,可以在原来基础上进行修改
#article/views.py修改
from django.shortcuts import render
from django.http import HttpResponse
from .models import ArticlePost
# Create your views here.
def article_list(request):
articles = ArticlePost.objects.all()
context = { 'articles': articles }
return render(request, 'article/list.html', context)
大佬分析的:
from .models import ArticlePost从models.py中导入ArticlePost数据类
ArticlePost.objects.all()是数据类的方法,可以获得所有的对象(即博客文章),并传递给articles变量
context定义了需要传递给模板的上下文,这里即articles
个人理解就是引入了一个中间量,把前端和后端链接起来,上面就是后端这一部分
10.编写模板
在项目文件夹下创建templates/article文件夹,并创建templates/article/list.html文件
结构如下
tyrant@ubuntu:~/Desktop/Django/Tk_blog$ tree
.
├── article
│ ├── admin.py
│ ├── apps.py
│ ├── __init__.py
│ ├── migrations
│ │ ├── 0001_initial.py
│ │ ├── __init__.py
│ │ └── __pycache__
│ │ ├── 0001_initial.cpython-37.pyc
│ │ └── __init__.cpython-37.pyc
│ ├── models.py
│ ├── __pycache__
│ │ ├── admin.cpython-37.pyc
│ │ ├── __init__.cpython-37.pyc
│ │ ├── models.cpython-37.pyc
│ │ ├── urls.cpython-37.pyc
│ │ └── views.cpython-37.pyc
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── db.sqlite3
├── manage.py
├── templates
│ └── article
│ └── list.html
└── Tk_blog
├── asgi.py
├── __init__.py
├── __pycache__
│ ├── __init__.cpython-37.pyc
│ ├── settings.cpython-37.pyc
│ ├── urls.cpython-37.pyc
│ └── wsgi.cpython-37.pyc
├── settings.py
├── urls.py
└── wsgi.py
个人理解这是变量链接的前端这一部分
#templates/article/list.html配置
{% for article in articles %}
<p>{{ article.title }}</p>
{% endfor %}
Tk_blog/settings.py的TEMPLATES部分修改
#Tk_blog/settings.py的TEMPLATES部分修改
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, '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',
],
},
},
]
有点复杂...成品图搞成了倒是...贴出来代码吧,中间过程跟大佬不太一样可能是版本原因,中间改代码改的错误都没了,对比可以看大佬的代码
文件结构
tyrant@ubuntu:~/Desktop/Django/Tk_blog$ tree -L 1
.
├── article
├── db.sqlite3
├── manage.py
├── static
├── templates
└── Tk_blog
tyrant@ubuntu:~/Desktop/Django/Tk_blog/templates$ tree
.
├── article
│ └── list.html
├── base.html
├── footer.html
└── header.html
#文件结构大概是这样的,static打包成zip搞个链接放在这里,大概看一下源码理解一下就懂了
static文件夹:链接:https://pan.baidu.com/s/1vfFhhD7k3IPHzlcHWe6-jQ 提取码:9alr
#Tk_blog/templates/base.html
<!-- 载入静态文件 -->
{% load static %}
<!DOCTYPE html>
<!-- 网站主语言 -->
<html lang="zh-cn">
<head>
<!-- 网站采用的字符编码 -->
<meta charset="utf-8">
<!-- 预留网站标题的位置 -->
<title>{% block title %}{% endblock %}</title>
<!-- 引入bootstrap的css文件 -->
<link rel="stylesheet" href="{% static 'bootstrap/css/bootstrap.min.css' %}">
</head>
<body>
<!-- 引入导航栏 -->
{% include 'header.html' %}
<!-- 预留具体页面的位置 -->
{% block content %}{% endblock content %}
<!-- 引入注脚 -->
{% include 'footer.html' %}
<!-- bootstrap.js 依赖 jquery.js 和popper.js,因此在这里引入 -->
<script src="{% static 'jquery/jquery.js' %}"></script>
<script src="{% static 'popper/popper.js' %}"></script>
<!-- 引入bootstrap的js文件 -->
<script src="{% static 'bootstrap/js/bootstrap.min.js' %}"></script>
</body>
</html>
#Tk_blog/templates/footer.html
{% load static %}
<!-- Footer -->
<div>
<br><br><br>
</div>
<footer class="py-3 bg-dark fixed-bottom">
<div class="container">
<p class="m-0 text-center text-white">Copyright © www.dusaiphoto.com 2018</p>
</div>
</footer>
#Tk_blog/templates/header.html
<!-- 定义导航栏 -->
<nav class="navbar navbar-expand-lg navbar-dark bg-dark">
<div class="container">
<!-- 导航栏商标 -->
<a class="navbar-brand" href="#">我的博客</a>
<!-- 导航入口 -->
<div>
<ul class="navbar-nav">
<!-- 条目 -->
<li class="nav-item">
<a class="nav-link" href="#">文章</a>
</li>
</ul>
</div>
</div>
</nav>
#Tk_blog/templates/article/list.html
<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %}
{% load static %}
<!-- 写入 base.html 中定义的 title -->
{% block title %}
首页
{% endblock title %}
<!-- 写入 base.html 中定义的 content -->
{% block content %}
<!-- 定义放置文章标题的div容器 -->
<div class="container">
<div class="row mt-2">
{% for article in articles %}
<!-- 文章内容 -->
<div class="col-4 mb-4">
<!-- 卡片容器 -->
<div class="card h-100">
<!-- 标题 -->
<h4 class="card-header">{{ article.title }}</h4>
<!-- 摘要 -->
<div class="card-body">
<p class="card-text">{{ article.body|slice:'100' }}...</p>
</div>
<!-- 注脚 -->
<div class="card-footer">
<a href="#" class="btn btn-primary">阅读本文</a>
</div>
</div>
</div>
{% endfor %}
</div>
</div>
{% endblock content %}
单篇文章显示设置
修改文件Tk_blog/article/views.py,在后面附加如下函数
def article_detail(request, id):
# 取出相应的文章
article = ArticlePost.objects.get(id=id)
# 需要传递给模板的对象
context = { 'article': article }
# 载入模板,并返回context对象
return render(request, 'article/detail.html', context)
修改Tk_blog/article/urls.py
from django.urls import path
from . import views
app_name = 'article'
urlpatterns = [
path('article-list/', views.article_list, name='article_list'),# 目前还没有urls
path('article-detail/<int:id>/', views.article_detail, name='article_detail'),
]
对应路径下创建detail.html
#templates/article/detail.html
<!-- extends表明此页面继承自 base.html 文件 -->
{% extends "base.html" %}
{% load staticfiles %}
<!-- 写入 base.html 中定义的 title -->
{% block title %}
文章详情
{% endblock title %}
<!-- 写入 base.html 中定义的 content -->
{% block content %}
<!-- 文章详情 -->
<div class="container">
<div class="row">
<!-- 标题及作者 -->
<h1 class="col-12 mt-4 mb-4">{{ article.title }}</h1>
<div class="col-12 alert alert-success">作者:{{ article.author }}</div>
<!-- 文章正文 -->
<div class="col-12">
<p>{{ article.body }}</p>
</div>
</div>
</div>
{% endblock content %}
访问http://127.0.0.1:8000/article/article-detail/1/
,测试
优化文章入口,实现跳转
#修改header.py对应语句
<a class="nav-link" href="{% url 'article:article_list' %}">文章</a>
#修改list.py对应语句
<a href="{% url 'article:article_detail' article.id %}" class="btn btn-primary">阅读本文</a>