基于Django框架对MongoDB实现增删改查

在上一篇中,咱们已经实现了Scrapy框架爬取数据,并且存储到Mongodb数据库,
接下来呢,,,,,,,,,,,,,
咱们就要对这些数据进行操作。

目标:从Mongodb数据库取出数据,通过Django框架展示到web页面,实现展示、分页、添加、修改、删除的功能

1. 准备工作

创建django项目
点击:file–>new project,出现下面的对话框。
这里写图片描述
选择Django栏目,输入项目名称,选择python解释器版本,点击create创建。
这里写图片描述

创建APP
在pycharm下方的terminal终端中输入命令:

  python manage.py startapp cmdb

这样就创建了一个叫做cmdb的APP,django自动生成“cmdb”文件夹。

具体详见django新手教程

2. 连接mongodb数据库(cmdb/models.py)


from django.db import models
from mongoengine import *

# Create your models here.

# 指明要连接的数据库
connect('Complaint',host = '127.0.0.1',port = 27017)

class invitation(Document):
    # 定义数据库中的所有字段
    number = StringField()
    title = StringField()
    content = StringField()
    url = StringField()

    # 指明连接的数据表名
    meta = {'collection':'invitation'}

# 测试是否连接成功
# for i in invitation.objects[:10]:
#     print(i.title)

3. 配置相关设置(ComplaintDjango/settings.py)


"""
Django settings for ComplaintDjango project.

Generated by 'django-admin startproject' using Django 2.0.5.

For more information on this file, see
https://docs.djangoproject.com/en/2.0/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/2.0/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.0/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '4c-=!&(4kx9xhrz=e1%((vx#!*v%2pbot$2sss7k6*c$yw@t*e'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    # csrf跨站请求保护机制,暂时先关闭,或者在form表单里添加一个`{% csrf_token %}`标签。
    #'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
]

ROOT_URLCONF = 'ComplaintDjango.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # 配置html
        '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',
            ],
        },
    },
]

WSGI_APPLICATION = 'ComplaintDjango.wsgi.application'


# Database
# https://docs.djangoproject.com/en/2.0/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': None,
    }
}
# 连接mongodb数据库
from mongoengine import connect
connect('Complaint')

# Password validation
# https://docs.djangoproject.com/en/2.0/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/2.0/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.0/howto/static-files/

STATIC_URL = '/static/'
# 配置静态文件
STATICFILES_DIRS = (
    os.path.join(BASE_DIR,'static'),
)

4. 路由(ComplaintDjango/urls.py)

路由都在urls文件里,它将浏览器输入的path映射到相应的业务处理逻辑。

简单编写方法如下:


from django.contrib import admin
from django.urls import path
# 导入对应 app 的 views 文件
from cmdb import views

urlpatterns = [
    # 首页,展示页面
    path('index/',views.index),
    # 跳转到添加页面
    path('toAdd/',views.toAdd),
    # 添加到数据库
    path('addInvitation/',views.addInvitation),
    # 跳转到修改页面,进行数据回显
    path('toUpdate/',views.toUpdate),
    # 修改数据
    path('updateInvitation/',views.updateInvitation),
    # 删除数据
    path('delete/',views.delete)
]

5.业务处理逻辑(cmdb/views.py)

业务处理逻辑都在views.py文件里。


from django.shortcuts import render
from cmdb.models import invitation
from django.core.paginator import Paginator # 分页
from django.http import HttpResponseRedirect
# Create your views here.

# 展示、分页
def index(request):
    # 限制每一页显示的条目数量
    limit = 10
    # 查询所有的数据
    article = invitation.objects
    paginator = Paginator(article,limit)
    # 从url中获取页码参数
    page_num = request.GET.get('page',1)
    loaded = paginator.page(page_num)
    context = {
        'invitation':loaded
    }
    return render(request,"index.html",context)

# 进入添加页面
def toAdd(request):
    return render(request,"add.html")

# 添加
def addInvitation(request):
    if request.method == 'POST':
        number = request.POST.get("number",None)
        title = request.POST.get("title",None)
        content = request.POST.get("content",None)
        url = request.POST.get("url",None)
        tit = "提问:" + str(title) + "  编号:" + str(number)
        # 添加到数据库
        invi = invitation(number = number,title = tit,content = content,url = url)
        invi.save()
    return HttpResponseRedirect('/index/')

# 回显
def toUpdate(request):
    if request.method == 'GET':
        number = request.GET.get("number",None)
        # 根据条件查询数据
    invi = invitation.objects.filter(number=number)
    context = {
        'invitation':invi
    }
    return render(request,"update.html",context)

# 修改
def updateInvitation(request):
    if request.method == 'POST':
        number = request.POST.get("number", None)
        title = request.POST.get("title", None)
        content = request.POST.get("content", None)
        url = request.POST.get("url", None)
        # 根据条件修改数据
        invi = invitation.objects.filter(number=number).update(title=title,content=content,url=url)
    return HttpResponseRedirect('/index/')

# 删除
def delete(requeset):
    if requeset.method == 'GET':
        number = requeset.GET.get("number",None)
    # 删除数据
    invi = invitation.objects.filter(number=number).delete()
    return HttpResponseRedirect('/index/')


6.Html页面

首页(templates/index.html)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>首页</title>
</head>
<script type="text/javascript" src="static/js/jquery-1.8.2.min.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/index_work.css">
<body>
    <a href="/toAdd/">添加</a>
    <table>
        <thead>
            <th>编号</th>
            <th>标题</th>
            <th>内容</th>
            <th>链接</th>
            <th>操作</th>
        </thead>
        <tbody>
            {% for item in invitation %}
                <tr>
                    <td>{{ item.number }}</td>
                    <td>{{ item.title }}</td>
                    <td>{{ item.content }}</td>
                    <td><a>{{ item.url }}</a></td>
                    <td>
                        <a href="/toUpdate/?number={{ item.number }}"><input type="button" value="修改"></a>
                        <a href="/delete/?number={{ item.number }}"><input type="button" value="删除"></a>
                    </td>
                </tr>
            {% endfor %}
            <tr>
                <th colspan="6">
                    {% if invitation.has_previous %}
                    <a href="?page={{ invitation.previous_page_number }}"><input type="button" value="上一页"></a>
                    {% endif %}
                    <span>{{ invitation.number }} of {{ invitation.paginator.num_pages }}</span>
                    {% if invitation.has_next %}
                        <a href="?page={{ invitation.next_page_number }}"><input type="button" value="下一页"></a>
                    {% endif %}
                </th>
            </tr>
        </tbody>
    </table>
</body>
</html>

这里写图片描述
添加页面(templates/add.html)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>添加帖子</title>
</head>
<script type="text/javascript" src="static/js/jquery-1.8.2.min.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/index_work.css">
<body>
    <form action="/addInvitation/" method="post">
        编号:<input type="text" name="number" style="width: 500px"><br>
        标题:<input type="text" name="title" style="width: 500px"><br>
        内容:<br><textarea name="content" style="width: 550px;height: 200px"></textarea><br>
        链接:<input type="text" name="url" style="width: 500px"><br>
        <input type="submit" value="发布">
    </form>
</body>
</html>

这里写图片描述
修改页面(templates/update.html)


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>修改</title>
</head>
<script type="text/javascript" src="static/js/jquery-1.8.2.min.js"></script>
<link rel="stylesheet" type="text/css" href="../static/css/index_work.css">
<body>
    <form action="/updateInvitation/" method="post">
        {% for i in invitation %}
            编号:<input type="text" name="number" value="{{ i.number }}" style="width: 500px" readonly="true"><br>
            标题:<input type="text" name="title" value="{{ i.title }} " style="width: 500px"><br>
            内容:<br><textarea name="content" style="width: 550px;height: 200px">{{ i.content }}</textarea><br>
            链接:<input type="text" name="url" value="{{ i.url }}" style="width: 500px"><br>
            <input type="submit" value="确认修改">
        {% endfor %}
    </form>
</body>
</html>

这里写图片描述

注意:修改是先回显后改的过程,回显时,对 number 设置为 readonly = “true”,千万不要设置为 disabled = “true” ,最重要的一点原因:当表单提交时,这个表单输入项将不会被提交。

为小主奉上所有代码(〃’▽’〃)

猜你喜欢

转载自blog.csdn.net/qq_41139341/article/details/81667082