Django留言板项目完整搭建

1.新建python虚拟环境

新建一个文件夹

系统变量里添加这个WORKON_HOME变量,然后将刚才的文件夹路径填进去再重启(可将虚拟环境新建在指定路径,不然会建在C盘)

这里使用的WORKON_HOME变量值为D:\DjangoVir

建立新的文件夹中右键进入cmd

pip install virtualenvwrapper-win(有的话不用安装)

mkvirtualenv -p D:\Anaconda3\python.exe mxonline

2.安装Django并新建Django项目

pip install django==2.2 -i https://pypi.douban.com/simple

在pycharm中新建Django项目-选择已存在的解释器-选择刚才新建的python虚拟环境下的python.exe

在More Settings-Application name中填入“应用名”

这里使用的应用名为message_form

3.生成的目录说明

1.其中自动创建的"应用名“文件夹下的migrations文件夹,在数据库迁移时用到

2.其中的templates文件夹用来存放html文件

3.manage.py为启动Django项目的入口文件

4.新建一些目录

1.在项目中New一个Directory-命名为static,用来存放js、css、图片等文件

2.在项目中New一个Directory-命名为media,用来存放用户上传的文件、图片等

3.Django项目变大的时候应用会增多,此时在项目中New一个Python Package命名为apps

将建立的应用文件夹"应用名_form"拖动到apps中,采用拖动的方式可以对应修改配置(要勾选Search for references)

4.之后会引入一些第三方应用,此时在项目中New一个Python Package命名为extra_apps,用来存放第三方源码

5.再在项目中New一个File命名为requirements.txt,用来记录项目依赖于哪些第三方包,写入:

django==2.2

备注:

1.进入虚拟环境的命令

workon mxonline

2.可以用Django的命令来新建应用,有两种方式:

注:在创建Django项目时,未在More Settings-Application name中填入“应用名”时需要通过这种方法来手动创建

1.cmd

cd到项目所在目录下

输入:python manage.py startapp 应用名

2.Pycharm

菜单栏-Tools-run setup.py Task

输入:startapp 应用名

注:

使用Django命令来新建应用时,settings.py中:

INSTALLED_APPS中并没有被配置,要进行手动配置

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    # 手动添加
    'apps.应用名.apps.应用名Config'
]

mysql数据库密码:root

3.配置访问html页面的url

将”留言板.html“粘贴到templates文件夹下,右键-Rename为message_form.html

菜单栏-Run-Run-选择Django项目

控制台显示Django的默认端口为:http://127.0.0.1:8000/

粘贴到浏览器中进行访问,显示:在这里插入图片描述

Django有自动配置的admin后台管理系统,输入http://127.0.0.1:8000/admin可查看在这里插入图片描述

在Message中的urls.py中可以看到默认配置的admin:

urlpatterns = [
    path('admin/', admin.site.urls),
]

在message_form的view.py中定义一个函数:

from django.shortcuts import render
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    return render(request,"message_form.html")

在Message中的urls.py进行配置添加:

from apps.message_form.views import message_form
urlpatterns = [
    path('admin/', admin.site.urls),
    path('message_form/', message_form),
]

运行Django项目,文件修改时会自动重启

浏览器中输入http://127.0.0.1:8000/message_form
在这里插入图片描述

4.配置html页面显示(将html和css分离)

在实际开发过程中,一般要将html文件和css样式分离

1.进行全局的分离设置(一般使用此方法)

在项目根目录下的static文件夹中新建一个css文件夹,再在此文件夹下新建一个Stylesheet文件(css),命名为style

将message_form.html中的整个<style>标签剪贴到style.css中,再将<style>和</style>删除

在message_form.html中添加link

<link rel="stylesheet" href="/static/css/style.css">

在Message\settings.py中进行配置:

推荐使用相对路径:

STATIC_URL = '/static/'
# 指明在哪里搜索静态文件
STATICFILES_DIRS = [
    # 若有多个搜索目录可以添加到这个list中
    # 使用相对路径
	os.path.join(BASE_DIR, 'static')
]

或者可以使用绝对路径(不推荐)

STATIC_URL = '/static/'
# 指明在哪里搜索静态文件
STATICFILES_DIRS = [
    # 若有多个搜索目录可以添加到这个list中、
    # 右键-Copy path路径,将\改为/防止出现转义问题
	"D:/Message/static"
]

重新启动Django项目

刷新浏览器中的http://127.0.0.1:8000/message_form/

运行的样式和之前相同,即成功分离

2.也可以在单独的app中做分离

删掉message_form.html中的:

<link rel="stylesheet" href="/static/css/style.css">

在message_form文件夹中新建一个static文件夹,再在此文件下新建一个css文件夹,再在此文件夹下新建一个Stylesheet文件(css),命名为style

将message_form.html中的整个<style>标签剪贴到style.css中,再将<style>和</style>删除

在message_form.html中添加link

<link rel="stylesheet" href="/static/css/style.css">

重新启动Django项目

刷新浏览器中的http://127.0.0.1:8000/message_form/

运行的样式和之前相同,即成功分离

总结:

配置一个html页面显示的步骤:

1.配置url

2.配置对应的views逻辑

3.拆分静态(css,js,images)放入到static,html放到template下

​ (1)可以放到全局的template和static目录之下

​ (2)也可以放到对应的app下面

4.配置全局的static文件访问路径的配置STATICFILES_DIRS

5.设计数据库表

1.在Navicat中新建数据库mxonline,字符集选择utf8 – UTF-8 Unicode,排序规则选择utf8_general_ci

2.菜单栏-Tools-Run manage.py Task

输入命令makemigrations

会看到"No changes detected",因为没有设计model,所以没有变化

输入命令migrate,将记录同步到表当中

会看到在创建表,表会映射到数据库中,但默认为sqlite,所以还不能映射到mysql

在Message\settings.py中进行配置数据库:

在setting中可以看到使用的默认数据库是sqlite,要改为mysql

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': "mxonline",
        'USER': "root",
        'PASSWORD': "root",
        # 若是线上的可以指向线上的地址
        'HOST': "127.0.0.1"
    }
}

安装mysql驱动:

在windows下mysql驱动安装容易出错,在https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysqlclient手动下载安装包mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl

在下载位置的文件框中输入cmd,再进入虚拟环境workon mxonline

进行安装pip install mysqlclient-1.4.6-cp37-cp37m-win_amd64.whl

重新运行Django项目,若没有报错,进行migrate

菜单栏-Tools-Run manage.py Task

输入命令makemigrations

输入命令migrate

会看到在创建表,表会映射到mysql数据库中

在Navicat中可看到Django新建了内置的表
在这里插入图片描述

生成了这些表便可以自己定义model

3.定义model

在apps/message_form/models.py中定义表:

from django.db import models

# Create your models here.
class Message(models.Model):# 继承models.Model
    # 定义字段
    # max_length为必填字段,对应数据库中的varchar类型,verbose_name可理解为注释,并设置为主键
    name = models.CharField(max_length=20, verbose_name="姓名",primary_key=True)
    # EmailField是在CharField上的封装,会检测是否为邮箱,按住CTRL+左键点入可看到,已经默认设置了max_length,为254
    email = models.EmailField(verbose_name="邮箱")
    address = models.CharField(max_length=100, verbose_name="联系地址")
    # TextField不限字段长度
    message = models.TextField(verbose_name="留言信息")

    # 表中的meta信息
    class Meta:
        verbose_name = "留言信息"
        verbose_name_plural = verbose_name
        # 可以自己指定表名
        # 可以自己指定表名
        db_table = "message"

        # 若不指定表名,会生成名为message_form_message的表,表的命名为“app名称_类的名称(将大写转化为了小写)”

注:
在Message\settings.py中如果没有进行配置,models不会生成表

(此时已经配置,自己后加的app要进行配置)

INSTALLED_APPS = [
	# 省略
    'apps.message_form.apps.MessageFormConfig',
]

4.此时进行makemigrate和migrate,便可以将表直接做映射

菜单栏-Tools-Run manage.py Task

输入命令makemigrations

显示Create model Message,此时在migrations文件夹中生成了py文件,记录了所做操作

输入命令migrate

显示Applying message_form.0001_initial,会应用刚才生成的文件

在Navicat中可看到,生成了名为message的表
在这里插入图片描述

6.通过Django提供的models来进行对数据库的增删改查

从models中获取数据:

在Navicat中双击表message,输入测试数据,CRTL+S保存

在这里插入图片描述

1.使用all()方法

(1)QuerySet可以进行for操作

在message_form的view.py中:

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # all()取出所有数据,返回QuerySet对象,允许进行多种操作
    all_messages = Message.objects.all()
    # QuerySet类型可以进行for操作,遍历取出来的所有数据
    for message in all_messages:
        print(message.name)
    # 输出bobby
    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

可看到控制台输出bobby

QuerySet对象经过for循环才可以变成message对象

(2)QuerySet还可以进行切片操作,当做列表

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # all()取出所有数据,返回QuerySet对象,允许进行多种操作
    # 从索引0开始取,直到索引1为止,但不包括索引1
    all_messages = Message.objects.all()
    sliced_query = Message.objects.all()[:1]
    print(all_messages)
    # 输出:<QuerySet [<Message: Message object (bobby)>]>
    
    # 用.query方法来打印sql语句
    print(all_messages.query)
    # 输出:SELECT message.name, message.email, message.address, message.message FROM message
    print(sliced_query.query)
    # 输出:SELECT message.name, message.email, message.address, message.message FROM message  LIMIT 1
    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

可看到控制台输出:

<QuerySet [<Message: Message object (bobby)>]>
SELECT message.name, message.email, message.address, message.message FROM message
SELECT message.name, message.email, message.address, message.message FROM message LIMIT 1

注:QuerySet本身并没有执行sql操作

用.query方法来打印sql语句

2.可以使用filter方法进行设置查询条件

相当于sql中的WHERE

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # 使用filter
    all_messages = Message.objects.filter(name="bobby")
    print(all_messages.query)
    # 输出:SELECT `message`.`name`, `message`.`email`, `message`.`address`, `message`.`message` FROM `message` WHERE `message`.`name` = bobby
    for message in all_messages:
        print(message.name)
    # 输出:bobby
    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

可看到控制台输出:

SELECT message.name, message.email, message.address, message.message FROM message WHERE message.name = bobby
bobby

3.使用get()方法

get返回的是一个对象,数据不存在或者有多条数据存在会抛出异常

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # 3.使用get
    # message = Message.objects.get(name="bobby")
    # print(message.name)
    # # 输出:bobby

    # name="bobby1"不存在或者有多个时候会抛出异常
    message = Message.objects.get(name="bobby1")
    print(message.name)
    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

此时会在网页显示错误:A server error occurred. Please contact the administrator.

这是Django的一个bug

在控制台左键此位置

在这里插入图片描述

修改debug.py的第331行,将open()改为open(encoding=“utf-8”)

with Path(CURRENT_DIR, 'templates', 'technical_500.html').open(encoding="utf-8") as fh:

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

便会出现Django异常栈的页面

在这里插入图片描述

可以定位到是哪一行代码出错

在这里插入图片描述

可以进行异常的处理:

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # name="bobby1"不存在或者有多个时候会抛出异常
    try:
        message = Message.objects.get(name="bobby1")

    # 不存在的异常
    except Message.DoesNotExist as e:
        print(e)
        # 输出异常Message matching query does not exist.

    # 存在多个的异常
    except Message.MultipleObjectsReturned as e:
        print(e)

    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面,正常运行

4.进行删除delete()

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    all_messages = Message.objects.filter(name="bobby")
    all_messages.delete()
    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

在Navicat中可看到数据已被删除

5.进行数据的插入

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # 进行数据的插入操作
    # 实例化一个Message对象
    message = Message()
    message.name = "bobby"
    message.email = "bobby@imooc.com"
    message.address = "北京市"
    message.message = "留言"
    # 使用save方法将数据保存到数据库中,save方法如果存在则更新,不存在则插入
    message.save()
    return render(request,"message_form.html")

在Navicat中可看到数据已被插入

6.从前端页面html中提取数据保存到数据库中

html在提交表单时有两种方式:

(1)通过json提交

(2)通过html本身的form表单提交(这里采用此方式)

form action对应urls.py中配置的path(‘message_form/’, message_form)

修改message_form.html中:

<form action="/message_form/" method="post" class="smart-green">

</form>之前添加{% csrf_token %}

    {% csrf_token %}
</form>

若没有添加,会报错:

Forbidden (403)

CSRF verification failed. Request aborted.

Reason given for failure:

CSRF token missing or incorrect.

注:这是安全限制,来防止网络攻击

之后所有的form表单的提交都要加上{% csrf_token %}

用一个url可以完成两个功能:

1.get取数据,拉,将数据从服务器拉到本地进行展示,浏览器本身发起的是get请求

2.post,推,将本地的数据推到服务器进行保存,通过form表单提交时浏览器发起的是post请求

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # 从html中提取数据保存到数据库中
    # 如果是POST,进行取数据
    if request.method == "POST":
        # 进行值的提取
        # POST属性调用get方法,可理解为dict字典所有用get方法,""代表值不存在的话设置默认值
        name = request.POST.get("name","")
        email = request.POST.get("email", "")
        address = request.POST.get("address", "")
        message_text = request.POST.get("message", "")

        message = Message()
        # 和上面对应
        message.name = name
        message.email = email
        message.address = address
        message.message = message_text
        message.save()
    # 如果是get,直接render页面
    return render(request,"message_form.html")

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

可看到数据被添加到了数据库中

在这里插入图片描述

7.数据保存到服务器之后,从服务器中提取出数据展示到html页面

在message_form的view.py中:

from django.shortcuts import render

from apps.message_form.models import Message
# 默认接受一个参数request,是Django传递进来的,每一个请求都会包装成一个request对象
def message_form(request):
    # 从html中提取数据保存到数据库中
    # 如果是POST,进行取数据
    if request.method == "POST":
        # 进行值的提取
        # POST属性调用get方法,可理解为dict字典所有用get方法,""代表值不存在的话设置默认值
        name = request.POST.get("name","")
        email = request.POST.get("email", "")
        address = request.POST.get("address", "")
        message_text = request.POST.get("message", "")

        message = Message()
        # 和上面对应
        message.name = name
        message.email = email
        message.address = address
        message.message = message_text
        message.save()
        return render(request,"message_form.html", {
                "message":message
            })
    
    # 从服务器中提取出数据展示到html页面
    if request.method == "GET":
        var_dict = {}
        # 这里取数据使用filter方法,如果没有数据会返回一个空的list
        all_message = Message.objects.filter()
        if all_message:# 判断是否有数据,若没有数据取第0个会报错
            message = all_message[0]# 取第0个时会直接转为message对象而不是原来的QuerySet
            # 将views中的数据传到html页面中,传入一个字典{},键值对的名称可以任意写,值需要为message
            var_dict = {
                "message":message
            }
            return render(request,"message_form.html", var_dict)
            # 或者可以直接写为:locals(),可以将所有的局部变量全部变成key-value的形式,但此习惯不好
            # return render(request, "message_form.html", locals())
        else:# 若没有数据直接返回页面,不然会抛异常
            return render(request, "message_form.html")

在message_form.html中:

将值展示到input里面,只需将值赋到value中

<input id="name" type="text" value="{{ message .name}}" name="name" class="error" placeholder="请输入您的姓名"/>
<input id="email" type="email" value="{{ message.email }}" name="email" placeholder="请输入邮箱地址"/>
<input id="address" type="text" value="{{ message.address }}" name="address" placeholder="请输入联系地址"/>
<textarea id="message" name="message"  placeholder="请输入你的建议">{{ message.message }}</textarea>

重新进入页面,可以发现数据被显示到html页面

在这里插入图片描述

8.Django的template语法

可参考Django文档:https://docs.djangoproject.com/zh-hans/2.1/ref/templates/builtins/#if

在message_form.html中改写逻辑:

如果名字为bobby,则显示为bobbytest

<input id="name" type="text" value="{% if message.name == 'bobby'%}bobbytest{% endif %}" name="name" class="error" placeholder="请输入您的姓名"/>

菜单栏-Run-Debug-运行Django项目,在网页中刷新页面

可看到姓名显示为bobbytest

如果以bo开头的,则显示为bobbytest

使用slice方法截取字符,这里截取2个

<input id="name" type="text" value="{% if message.name|slice:'2' == 'bo'%}bobbytest{% endif %}" name="name" class="error" placeholder="请输入您的姓名"/>

Github托管

代码已托管到Github

  • 4
    点赞
  • 47
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值