在Ubuntu上使用Django开发CRM系统的步骤

写于

  1. 如果想在Windows上使用VSCode来开发,但是最终部署到Ubuntu上,可以使用VsCode的Remote-SSH插件,使用VSCode直接打开远程服务器的文件,并直接编辑

在Ubuntu上使用Django开发CRM系统的步骤

以下是在Ubuntu上使用Django开发CRM系统的步骤:

第一步:安装必要的软件

  1. 更新系统软件包

打开终端并运行以下命令更新系统软件包: bash sudo apt update sudo apt upgrade

  1. 安装Python和pip

Django需要Python支持。运行以下命令安装Python和pip: bash sudo apt install python3 python3-pip

  1. 安装Django

使用pip安装Django: bash pip3 install django

第二步:创建Django项目

  1. 创建项目目录

在你希望存储项目的目录中创建一个新的项目目录: bash mkdir my_crm_project cd my_crm_project

  1. 创建Django项目

使用以下命令创建一个新的Django项目: bash django-admin startproject crm

  1. 进入项目目录

进入新创建的项目目录: bash cd crm

第三步:创建Django应用

  1. 创建应用

使用以下命令创建一个新的Django应用,例如名为customers: bash python3 manage.py startapp customers

  1. 注册应用

打开crm/settings.py文件,在INSTALLED_APPS列表中添加customers: python INSTALLED_APPS = [ ... 'customers', ]

第四步:设置数据库

  1. 默认数据库配置

Django默认使用SQLite数据库。在crm/settings.py文件中可以看到如下配置: python DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': BASE_DIR / 'db.sqlite3', } }

  1. 迁移数据库

运行以下命令应用初始迁移: bash python3 manage.py migrate

第五步:创建超级用户

  1. 创建超级用户

运行以下命令创建一个超级用户,用于访问Django管理界面: bash python3 manage.py createsuperuser 按提示输入用户名、电子邮件和密码。root, 4***@qq.com,root

第六步:运行开发服务器

  1. 启动开发服务器

使用以下命令启动Django开发服务器: bash python3 manage.py runserver

  1. 访问开发服务器

打开浏览器,访问 http://127.0.0.1:8000/,你应该能看到Django欢迎页面。

  1. 访问管理界面

在浏览器中访问 http://127.0.0.1:8000/admin/,使用之前创建的超级用户登录,进入Django管理界面。

第七步:开发CRM功能

  1. 定义模型

打开customers/models.py文件,定义你需要的模型。例如: ```python from django.db import models

class Customer(models.Model): first_name = models.CharField(max_length=50) last_name = models.CharField(max_length=50) email = models.EmailField()

   def __str__(self):
       return f'{self.first_name} {self.last_name}'

```

  1. 迁移模型

运行以下命令创建并应用模型迁移: bash python3 manage.py makemigrations customers python3 manage.py migrate

  1. 注册模型

打开customers/admin.py文件,注册你的模型以便在管理界面中管理: ```python from django.contrib import admin from .models import Customer

admin.site.register(Customer) ```

  1. 创建视图和模板

根据你的需求创建视图和模板文件,处理用户请求和渲染响应。

第八步:前端开发

  1. 创建模板目录

在customers应用目录中创建templates/customers目录。

  1. 创建HTML模板

在templates/customers目录中创建HTML文件,如index.html,并编写前端代码。

  1. 定义视图

打开customers/views.py文件,定义视图函数。例如: ```python from django.shortcuts import render

def index(request): return render(request, 'customers/index.html') ```

  1. 配置URL

打开crm/urls.py文件,添加你的应用URL配置: ```python from django.urls import path from customers import views

urlpatterns = [ ... path('', views.index, name='index'), ] ```

这样,你就完成了在Ubuntu上使用Django开发CRM系统的基础设置。接下来,你可以根据具体需求继续完善系统的功能。

在这一步,完成了基本部署,但目前是空壳内容,需要完善内容

CRM系统架构设计

根据你的要求,我将为你的CRM系统设计一个包含AI情感分析模块的架构。以下是具体的模块设计:

1. 系统需求分析

功能需求

(1) 数据导入:支持从Excel文件导入客户评价数据。 (2) 数据管理:包括客户信息、评价信息的增删改查。 (3) 情感分析:分析客户评价中的情感,生成情感报告。 (4) 客户关系管理:记录和管理客户交互历史、反馈等信息。 (5) 报表与分析:生成客户满意度报告、情感分析报告等。 (6) 权限管理:不同用户角色(如管理员、分析师)有不同的权限。

非功能需求

(1) 系统性能:支持大规模数据处理和快速情感分析。 (2) 可用性:界面友好,易于使用。 (3) 安全性:确保数据的安全和隐私。

2. 数据库设计

(1) 数据导入模块

  • 实现从Excel文件导入客户评价数据的功能。可以使用Pandas读取Excel文件并将数据存入数据库。

(2) 客户管理模块

  • 实现客户信息的增删改查功能,包括显示客户列表、添加新客户、编辑客户信息、删除客户。

(3) 评价管理模块

  • 管理客户评价信息,包括评价内容的增删改查。

(4) 情感分析模块

  • 使用Python进行情感分析。可以使用NLTK、TextBlob或Transformers等库进行文本分析,提取评价中的情感信息并存储到数据库。

(5) 报表与分析模块

  • 提供多种报表和分析功能,如客户满意度报告、情感分析报告等,帮助企业决策。

(6) 权限管理模块

  • 根据用户角色分配不同的权限,确保数据安全。

4. 系统架构设计

前端

  • 使用HTML、CSS、JavaScript构建用户界面,可能使用React或Vue.js框架。

后端

  • 使用Django框架构建API,处理业务逻辑和数据库操作。

数据库

  • 使用PostgreSQL管理数据。

AI情感分析

  • 使用Python进行情感分析,可能用到的库包括NLTK、TextBlob、Transformers等。

5. 开发与测试

  • 制定详细的开发计划,分阶段实现各个模块。
  • 在每个阶段进行单元测试和集成测试,确保系统稳定性。

6. 维护与优化

  • 定期更新和优化系统功能,修复bug,提高性能。
  • 根据用户反馈,不断改进系统的用户体验和功能。

实现步骤

Step 1: 数据导入模块

  • 创建Django模型来表示客户信息和评价信息。
  • 编写脚本或视图函数,从Excel文件读取数据并存入数据库。

Step 2: 客户管理模块

  • 创建客户管理的视图和表单,使用Django的通用视图(Generic Views)简化开发。

Step 3: 评价管理模块

  • 创建评价管理的视图和表单,允许用户查看、添加、编辑和删除评价。

Step 4: 情感分析模块

  • 使用Python库进行文本分析,将评价文本分类为正面、负面或中性。
  • 创建定期任务(如使用Celery),定期对新的评价进行情感分析。

Step 5: 报表与分析模块

  • 使用Django的模板系统生成报表。
  • 可以使用Chart.js或D3.js等前端库生成可视化图表。

Step 6: 权限管理模块

  • 使用Django的认证和权限系统,定义不同用户角色的权限。

这是一个详细的CRM系统设计方案,重点在于情感分析模块的实现。如果有任何具体的问题或需求,欢迎随时提出。

前端

  1. 主页(Home) - 系统简介 - 功能概述 - 数据来源介绍
  2. 客户管理(Customers) - 客户信息查看、添加、编辑和删除 - 客户详细信息页,显示客户的所有评价记录和情感分析结果
  3. 评价管理(Reviews) - 评价信息查看、添加、编辑和删除 - 评价详细信息页,显示评价文本、情感分析结果、标签等
  4. 情感分析(Sentiment Analysis) - 情感分析结果展示,包括情感趋势图、情感分布图等 - 支持不同模型的情感分析结果对比
  5. 报表与分析(Reports) - 生成客户满意度报告 - 销售报告和其他分析报告

后端

后端使用Django框架,处理业务逻辑、数据库操作和与AI模块的交互。

  1. 数据导入模块 - 从Excel文件(如/mnt/data/20240101-20240331-评价列表.xlsx)导入客户评价数据 - 数据清洗和预处理(调用相关Python脚本)
  2. 客户管理模块 - 增删改查客户信息 - 关联客户评价信息
  3. 评价管理模块 - 增删改查评价信息 - 与情感分析模块交互,获取评价的情感分析结果
  4. 情感分析模块 - 调用预训练的情感分析模型(如CNN、LSTM、CNN-LSTM等),对评价文本进行情感分析 - 保存和展示情感分析结果
  5. 报表与分析模块 - 生成各类报表,支持导出PDF、Excel等格式 - 数据可视化

数据库

使用PostgreSQL管理数据。

  1. 客户信息表(Customers) - CustomerID, Name, Email, Phone, Address, CreatedAt, UpdatedAt
  2. 评价信息表(Reviews) - ReviewID, CustomerID, ReviewText, Rating, Sentiment, CreatedAt, UpdatedAt
  3. 情感分析结果表(SentimentAnalysis) - AnalysisID, ReviewID, Sentiment, ModelUsed, AnalysisDate

AI模块

使用Python和相关库(如TensorFlow、Keras、BERT等)实现情感分析和数据处理。

  1. 数据预处理 - 数据清洗、分词、同义词处理、标签提取等 - 生成处理后的数据文件(如data_jieba.csv, data_syn.csv等)
  2. 模型训练与评估 - 使用不同模型(CNN、LSTM、CNN-LSTM等)训练和评估情感分析模型 - 保存训练好的模型(如train_cnn_model.h5, train_ltsm_model.h5等)
  3. 情感分析 - 加载预训练模型,对新评价文本进行情感分析 - 返回分析结果,并保存到数据库

简单的CRM主页设计

当然可以,以下是一个简单的CRM主页设计草案,包括前端HTML/CSS和后端Django视图的一些基本代码示例。

CRM主页设计

前端HTML/CSS

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRM Home</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>Customer Relationship Management System</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'index' %}">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        <section>
            <h2>Welcome to the CRM System</h2>
            <p>This system helps you manage customer relationships and analyze sentiment from reviews to improve customer satisfaction.</p>
        </section>
    </main>
    <footer>
        <p>&copy; 2024 Your Company. All rights reserved.</p>
    </footer>
</body>
</html>

CSS (styles.css)

body {
    font-family: Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f4f4f4;
}

header {
    background-color: #333;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}

nav ul {
    list-style: none;
    padding: 0;
    background-color: #444;
    display: flex;
    justify-content: center;
    margin: 0;
}

nav ul li {
    margin: 0 1rem;
}

nav ul li a {
    color: #fff;
    text-decoration: none;
    padding: 0.5rem 1rem;
    display: block;
}

nav ul li a:hover {
    background-color: #555;
}

main {
    padding: 2rem;
    text-align: center;
}

footer {
    background-color: #333;
    color: #fff;
    text-align: center;
    padding: 1rem 0;
    position: fixed;
    width: 100%;
    bottom: 0;
}

Django视图和URL配置

views.py

from django.shortcuts import render

def home(request):
    return render(request, 'home.html')

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.home, name='index'),
    path('customers/', views.customers, name='customers'),
    path('reviews/', views.reviews, name='reviews'),
    path('sentiment_analysis/', views.sentiment_analysis, name='sentiment_analysis'),
    path('reports/', views.reports, name='reports'),
]

其他视图函数

你可以根据需要为其他页面添加视图函数,例如:

views.py

def customers(request):
    return render(request, 'customers.html')

def reviews(request):
    return render(request, 'reviews.html')

def sentiment_analysis(request):
    return render(request, 'sentiment_analysis.html')

def reports(request):
    return render(request, 'reports.html')

这是一个基本的CRM主页设计,包含了导航栏、欢迎信息和底部版权声明。你可以根据需要进一步扩展和美化页面。如果有任何具体的问题或需求,欢迎随时提出。

在网页中引入静态文件

确保静态文件配置正确

在你的settings.py中确保静态文件配置如下:

pythonCopy codeimport os

# 静态文件的URL
STATIC_URL = '/static/'

# 静态文件目录
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

文件结构确认

确保你的项目文件结构如下:

arduinoCopy codemy_crm_project/
    crm/
        settings.py
        urls.py
        ...
    customers/
        templates/
            customers/
                index.html
        static/
            customers/
                css/
                    index.css

正确引用静态文件

在你的index.html文件中,确保引用静态文件的代码如下:

htmlCopy code<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRM Home</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'customers/css/index.css' %}">
</head>
<body>
    <header>
        <h1>Customer Relationship Management System</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'index' %}">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        <section>
            <h2>Welcome to the CRM System</h2>
            <p>This system helps you manage customer relationships and analyze sentiment from reviews to improve customer satisfaction.</p>
        </section>
    </main>
    <footer>
        <p>&copy; 2024 Your Company. All rights reserved.</p>
    </footer>
</body>
</html>

图片放图床,图床用的postimages

主页美化

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CRM Home</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/index.css' %}">
</head>
<body>
    <header>
        <h1>Customer Relationship Management System</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'index' %}">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        <section class="intro">            
            <h2>Welcome to the CRM System</h2>
            <p>This CRM system is developed to enhance customer relationship management by leveraging AI-powered sentiment analysis. The primary purpose of this system is to analyze customer feedback and improve restaurant satisfaction based on sentiment insights.</p>
            <img src="https://site-1314099117.cos.ap-guangzhou.myqcloud.com/img/d5cfafdda15fcd34f453e8202fa0ddd4.crm.webp" alt="CRM System Image">
        </section>
        <section class="purpose">
            <h3>Purpose and Objectives</h3>
            <p>The CRM system aims to:</p>
            <ul>
                <li>Manage and analyze customer data efficiently.</li>
                <li>Utilize AI to perform sentiment analysis on customer reviews.</li>
                <li>Generate insightful reports to improve customer satisfaction and business strategies.</li>
            </ul>
        </section>
        <section class="modules">
            <h3>System Modules</h3>
            <ul>
                <li><strong>Data Import Module:</strong> Import customer review data from Excel files.</li>
                <li><strong>Customer Management Module:</strong> Add, edit, view, and delete customer information.</li>
                <li><strong>Review Management Module:</strong> Manage customer reviews and feedback.</li>
                <li><strong>Sentiment Analysis Module:</strong> Analyze customer sentiments using AI techniques.</li>
                <li><strong>Reports and Analytics Module:</strong> Generate reports on customer satisfaction and sentiment analysis.</li>
            </ul>
        </section>
        <section class="data-source">
            <h3>Data Source</h3>
            <p>This study collected extensive customer review data from the well-known restaurant chain Jiji Hong Hotpot. Founded on January 1, 2001, in Nanchang, Jiangxi, Jiji Hong Hotpot has deeply explored the Jiangxi market with a strong supply chain system and continues to plan for future development. The dataset includes customer review information from Jiji Hong's directly-operated stores within Jiangxi province.</p>
            <!-- <img src="https://i.postimg.cc/NfyjNp98/jijihong-design.jpg" alt="Data Source Image"> -->
            <img src="https://i.postimg.cc/3N0QZfSd/crm.jpg" alt="Data Source Image">
        </section>
    </main>
    <footer>
        <p>&copy; 2024 Liu Feisheng. All rights reserved.</p>
    </footer>
</body>
</html>

css

body {
    font-family: 'Helvetica Neue', Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f9f9f9;
    color: #333;
    line-height: 1.6;
}

header {
    background-color: #4CAF50;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}

nav ul {
    list-style: none;
    padding: 0;
    background-color: #333;
    display: flex;
    justify-content: center;
    margin: 0;
}

nav ul li {
    margin: 0 1rem;
}

nav ul li a {
    color: #fff;
    text-decoration: none;
    padding: 0.5rem 1rem;
    display: block;
}

nav ul li a:hover {
    background-color: #555;
}

main {
    padding: 2rem;
    max-width: 800px;
    margin: 0 auto;
}

h2, h3 {
    color: #4CAF50;
}

.intro, .purpose, .modules, .data-source {
    margin-bottom: 2rem;
}

.intro img, .modules img, .data-source img {
    width: 800px;
    height: auto;
    border-radius: 8px;
    margin-bottom: 1rem;
}

ul {
    text-align: left;
    display: inline-block;
    margin: 1rem auto;
}

footer {
    background-color: #333;
    color: #fff;
    text-align: center;
    padding: 1rem 0;
    position: fixed;
    width: 100%;
    bottom: 0;
}

调整为适应各种屏幕的网站

客户管理模型

好的,我们来设计客户管理模型的页面。这个页面将包括客户信息的查看、添加、编辑和删除功能。以下是客户管理页面的HTML和CSS代码。

客户管理页面HTML文件:customers.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Customer Management</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>Customer Management</h1>
    </header>
    <nav>
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        <section class="customer-list">
            <h2>Customer List</h2>
            <table>
                <thead>
                    <tr>
                        <th>ID</th>
                        <th>Name</th>
                        <th>Email</th>
                        <th>Phone</th>
                        <th>Actions</th>
                    </tr>
                </thead>
                <tbody>
                    {% for customer in customers %}
                    <tr>
                        <td>{{ customer.id }}</td>
                        <td>{{ customer.name }}</td>
                        <td>{{ customer.email }}</td>
                        <td>{{ customer.phone }}</td>
                        <td>
                            <a href="{% url 'edit_customer' customer.id %}">Edit</a> |
                            <a href="{% url 'delete_customer' customer.id %}">Delete</a>
                        </td>
                    </tr>
                    {% endfor %}
                </tbody>
            </table>
            <a href="{% url 'add_customer' %}" class="btn">Add New Customer</a>
        </section>
    </main>
    <footer>
        <p>&copy; 2024 Your Company. All rights reserved.</p>
    </footer>
</body>
</html>

添加/编辑客户页面HTML文件:customer_form.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% if customer %}Edit Customer{% else %}Add Customer{% endif %}</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <header>
        <h1>{% if customer %}Edit Customer{% else %}Add Customer{% endif %}</h1>
    </header>
    <nav>
        <ul>
            <li><a href="#">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        <section class="customer-form">
            <h2>{% if customer %}Edit Customer{% else %}Add Customer{% endif %}</h2>
            <form method="POST">
                {% csrf_token %}
                <label for="name">Name</label>
                <input type="text" id="name" name="name" value="{{ customer.name|default_if_none:'' }}" required>

                <label for="email">Email</label>
                <input type="email" id="email" name="email" value="{{ customer.email|default_if_none:'' }}" required>

                <label for="phone">Phone</label>
                <input type="text" id="phone" name="phone" value="{{ customer.phone|default_if_none:'' }}" required>

                <button type="submit" class="btn">{% if customer %}Update{% else %}Add{% endif %} Customer</button>
            </form>
        </section>
    </main>
    <footer>
        <p>&copy; 2024 Your Company. All rights reserved.</p>
    </footer>
</body>
</html>

更新后的CSS文件:styles.css

body {
    font-family: 'Helvetica Neue', Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f9f9f9;
    color: #333;
    line-height: 1.6;
}

header {
    background-color: #4CAF50;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}

nav ul {
    list-style: none;
    padding: 0;
    background-color: #333;
    display: flex;
    justify-content: center;
    margin: 0;
}

nav ul li {
    margin: 0 1rem;
}

nav ul li a {
    color: #fff;
    text-decoration: none;
    padding: 0.5rem 1rem;
    display: block;
}

nav ul li a:hover {
    background-color: #555;
}

main {
    padding: 2rem;
    max-width: 800px;
    margin: 0 auto;
}

h2, h3 {
    color: #4CAF50;
}

.customer-list, .customer-form {
    margin-bottom: 2rem;
}

.customer-list table {
    width: 100%;
    border-collapse: collapse;
    margin-bottom: 1rem;
}

.customer-list th, .customer-list td {
    border: 1px solid #ddd;
    padding: 0.5rem;
    text-align: left;
}

.customer-list th {
    background-color: #f2f2f2;
}

.customer-list td a {
    color: #4CAF50;
    text-decoration: none;
}

.customer-list td a:hover {
    text-decoration: underline;
}

.btn {
    display: inline-block;
    padding: 0.5rem 1rem;
    color: #fff;
    background-color: #4CAF50;
    text-decoration: none;
    border-radius: 4px;
    margin-top: 1rem;
}

.btn:hover {
    background-color: #45a049;
}

label {
    display: block;
    margin-top: 1rem;
}

input[type="text"], input[type="email"] {
    width: 100%;
    padding: 0.5rem;
    margin-top: 0.5rem;
    border: 1px solid #ddd;
    border-radius: 4px;
}

button[type="submit"] {
    display: inline-block;
    padding: 0.5rem 1rem;
    color: #fff;
    background-color: #4CAF50;
    text-decoration: none;
    border: none;
    border-radius: 4px;
    margin-top: 1rem;
}

button[type="submit"]:hover {
    background-color: #45a049;
}

footer {
    background-color: #333;
    color: #fff;
    text-align: center;
    padding: 1rem 0;
    position: fixed;
    width: 100%;
    bottom: 0;
}

@media (max-width: 768px) {
    nav ul {
        flex-direction: column;
    }

    nav ul li {
        margin: 0.5rem 0;
    }

    main {
        padding: 1rem;
    }

    h2, h3 {
        font-size: 1.5rem;
    }

    ul {
        width: 100%;
    }
}

@media (max-width: 480px) {
    header h1 {
        font-size: 1.5rem;
    }

    nav ul li a {
        padding: 0.5rem;
    }

    main {
        padding: 0.5rem;
    }

    h2, h3 {
        font-size: 1.2rem;
    }
}

Django视图函数和URL配置

views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Customer
from .forms import CustomerForm

def customers(request):
    customers = Customer.objects.all()
    return render(request, 'customers.html', {'customers': customers})

def add_customer(request):
    if request.method == "POST":
        form = CustomerForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('customers')
    else:
        form = CustomerForm()
    return render(request, 'customer_form.html', {'form': form})

def edit_customer(request, pk):
    customer = get_object_or_404(Customer, pk=pk)
    if request.method == "POST":
        form = CustomerForm(request.POST, instance=customer)
        if form.is_valid():
            form.save()
            return redirect('customers')
    else:
        form = CustomerForm(instance=customer)
    return render(request, 'customer_form.html', {'form': form, 'customer': customer})

def delete_customer(request, pk):
    customer = get_object_or_404(Customer, pk=pk)

用模板直接生成其他html文件

我们可以通过Django的模板继承功能来简化HTML文件。首先,我们创建一个基础模板,然后让各个页面模板继承这个基础模板。以下是详细步骤:

基础模板:base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}CRM System{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/index.css' %}">
</head>
<body>
    <header>
        <h1>Customer Relationship Management System</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'index' %}">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        {% block content %}
        {% endblock %}
    </main>
    <footer>
        <p>&copy; 2024 Liu Feisheng. All rights reserved.</p>
    </footer>
</body>
</html>

首页模板:index.html

{% extends "base.html" %}

{% block title %}CRM Home{% endblock %}

{% block content %}
<section class="intro">
    <h2>Welcome to the CRM System</h2>
    <p>This CRM system is developed to enhance customer relationship management by leveraging AI-powered sentiment analysis. The primary purpose of this system is to analyze customer feedback and improve restaurant satisfaction based on sentiment insights.</p>
    <img src="https://i.postimg.cc/3N0QZfSd/crm.jpg" alt="CRM System Image">
</section>
<section class="purpose">
    <h3>Purpose and Objectives</h3>
    <p>The CRM system aims to:</p>
    <ul>
        <li>Manage and analyze customer data efficiently.</li>
        <li>Utilize AI to perform sentiment analysis on customer reviews.</li>
        <li>Generate insightful reports to improve customer satisfaction and business strategies.</li>
    </ul>
</section>
<section class="modules">
    <h3>System Modules</h3>
    <ul>
        <li><strong>Data Import Module:</strong> Import customer review data from Excel files.</li>
        <li><strong>Customer Management Module:</strong> Add, edit, view, and delete customer information.</li>
        <li><strong>Review Management Module:</strong> Manage customer reviews and feedback.</li>
        <li><strong>Sentiment Analysis Module:</strong> Analyze customer sentiments using AI techniques.</li>
        <li><strong>Reports and Analytics Module:</strong> Generate reports on customer satisfaction and sentiment analysis.</li>
    </ul>
</section>
<section class="data-source">
    <h3>Data Source</h3>
    <p>This study collected extensive customer review data from the well-known restaurant chain Jiji Hong Hotpot. Founded on January 1, 2001, in Nanchang, Jiangxi, Jiji Hong Hotpot has deeply explored the Jiangxi market with a strong supply chain system and continues to plan for future development. The dataset includes customer review information from Jiji Hong's directly-operated stores within Jiangxi province.</p>
    <img src="https://i.postimg.cc/NfyjNp98/jijihong-design.jpg" alt="Data Source Image">
</section>
{% endblock %}

客户管理页面模板:customers.html

{% extends "base.html" %}

{% block title %}Customer Management{% endblock %}

{% block content %}
<section class="customer-list">
    <h2>Customer List</h2>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Email</th>
                <th>Phone</th>
                <th>Actions</th>
            </tr>
        </thead>
        <tbody>
            {% for customer in customers %}
            <tr>
                <td>{{ customer.id }}</td>
                <td>{{ customer.name }}</td>
                <td>{{ customer.email }}</td>
                <td>{{ customer.phone }}</td>
                <td>
                    <a href="{% url 'edit_customer' customer.id %}">Edit</a> |
                    <a href="{% url 'delete_customer' customer.id %}">Delete</a>
                </td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <a href="{% url 'add_customer' %}" class="btn">Add New Customer</a>
</section>
{% endblock %}

添加/编辑客户页面模板:customer_form.html

{% extends "base.html" %}

{% block title %}{% if customer %}Edit Customer{% else %}Add Customer{% endif %}{% endblock %}

{% block content %}
<section class="customer-form">
    <h2>{% if customer %}Edit Customer{% else %}Add Customer{% endif %}</h2>
    <form method="POST">
        {% csrf_token %}
        <label for="name">Name</label>
        <input type="text" id="name" name="name" value="{{ customer.name|default_if_none:'' }}" required>

        <label for="email">Email</label>
        <input type="email" id="email" name="email" value="{{ customer.email|default_if_none:'' }}" required>

        <label for="phone">Phone</label>
        <input type="text" id="phone" name="phone" value="{{ customer.phone|default_if_none:'' }}" required>

        <button type="submit" class="btn">{% if customer %}Update{% else %}Add{% endif %} Customer</button>
    </form>
</section>
{% endblock %}

Django视图函数和URL配置

views.py

from django.shortcuts import render, get_object_or_404, redirect
from .models import Customer
from .forms import CustomerForm

def index(request):
    return render(request, 'index.html')

def customers(request):
    customers = Customer.objects.all()
    return render(request, 'customers.html', {'customers': customers})

def add_customer(request):
    if request.method == "POST":
        form = CustomerForm(request.POST)
        if form.is_valid():
            form.save()
            return redirect('customers')
    else:
        form = CustomerForm()
    return render(request, 'customer_form.html', {'form': form})

def edit_customer(request, pk):
    customer = get_object_or_404(Customer, pk=pk)
    if request.method == "POST":
        form = CustomerForm(request.POST, instance=customer)
        if form.is_valid():
            form.save()
            return redirect('customers')
    else:
        form = CustomerForm(instance=customer)
    return render(request, 'customer_form.html', {'form': form, 'customer': customer})

def delete_customer(request, pk):
    customer = get_object_or_404(Customer, pk=pk)
    if request.method == "POST":
        customer.delete()
        return redirect('customers')
    return render(request, 'confirm_delete.html', {'customer': customer})

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('customers/', views.customers, name='customers'),
    path('customers/add/', views.add_customer, name='add_customer'),
    path('customers/edit/<int:pk>/', views.edit_customer, name='edit_customer'),
    path('customers/delete/<int:pk>/', views.delete_customer, name='delete_customer'),
]

通过以上步骤,我们创建了一个基础模板base.html,并让各个页面模板继承这个基础模板。这样可以避免重复代码,并使得代码更加整洁和易于维护。

客户和评价信息直接从excel导入

好的,以下是完整的models.py文件,其中包含了默认值设置,以确保在进行数据库迁移时不会遇到问题。

models.py

from django.db import models

class Customer(models.Model):
    name = models.CharField(max_length=100, default='Unknown')  # Default value added
    phone = models.CharField(max_length=20, default='')  # Default value added
    address = models.CharField(max_length=255, blank=True, null=True)

    def __str__(self):
        return self.name

class Review(models.Model):
    customer = models.ForeignKey(Customer, on_delete=models.CASCADE, related_name='reviews')
    review_text = models.TextField()
    sentiment = models.CharField(max_length=50, blank=True, null=True)

    def __str__(self):
        return f'Review by {self.customer.name}'

数据导入脚本

由于所有数据都来自Excel文件,我们还需要确保数据导入脚本正确处理这些字段。

management/commands/import_customers.py

import pandas as pd
from django.core.management.base import BaseCommand
from your_app.models import Customer, Review

class Command(BaseCommand):
    help = 'Import customers and reviews from an Excel file'

    def handle(self, *args, **kwargs):
        # Load Excel file
        file_path = 'path/to/your/excel/file.xlsx'
        df = pd.read_excel(file_path)

        for index, row in df.iterrows():
            customer, created = Customer.objects.get_or_create(
                name=row.get('Customer Name', 'Unknown'),
                defaults={
                    'phone': row.get('Phone', ''),
                    'address': row.get('Address', '')
                }
            )
            Review.objects.create(
                customer=customer,
                review_text=row.get('Review Text', ''),
                sentiment=row.get('Sentiment', '')
            )
        self.stdout.write(self.style.SUCCESS('Successfully imported data from Excel'))

数据库迁移

请确保你已经正确迁移了数据库,以反映模型中的更改。

  1. 生成迁移文件:
python manage.py makemigrations
  1. 应用迁移:
python manage.py migrate

运行管理命令

将Excel文件放置在项目的某个目录中,并在命令中指定文件路径。然后运行以下命令来导入数据:

python manage.py import_customers

更新视图和模板

为了展示这些数据,确保视图和模板已经正确配置。

views.py

from django.shortcuts import render
from .models import Customer, Review

def index(request):
    return render(request, 'index.html')

def customers(request):
    customers = Customer.objects.all()
    return render(request, 'customers.html', {'customers': customers})

def reviews(request):
    reviews = Review.objects.all()
    return render(request, 'reviews.html', {'reviews': reviews})

customers.html

{% extends "base.html" %}

{% block title %}Customer Management{% endblock %}

{% block content %}
<section class="customer-list">
    <h2>Customer List</h2>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Phone</th>
                <th>Address</th>
            </tr>
        </thead>
        <tbody>
            {% for customer in customers %}
            <tr>
                <td>{{ customer.id }}</td>
                <td>{{ customer.name }}</td>
                <td>{{ customer.phone }}</td>
                <td>{{ customer.address }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</section>
{% endblock %}

reviews.html

{% extends "base.html" %}

{% block title %}Review Management{% endblock %}

{% block content %}
<section class="review-list">
    <h2>Review List</h2>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Customer</th>
                <th>Review</th>
                <th>Sentiment</th>
            </tr>
        </thead>
        <tbody>
            {% for review in reviews %}
            <tr>
                <td>{{ review.id }}</td>
                <td>{{ review.customer.name }}</td>
                <td>{{ review.review_text }}</td>
                <td>{{ review.sentiment }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
</section>
{% endblock %}

更新URL配置

确保你的URL配置正确。

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('customers/', views.customers, name='customers'),
    path('reviews/', views.reviews, name='reviews'),
]

通过这些步骤,你可以确保你的Django项目正确导入并显示Excel文件中的客户和评价数据,而不需要进行编辑和修改。

在Django项目中,建议将Excel文件放在项目根目录或专门的目录(例如 data 或 imports)中。这样便于管理和访问。假设你将文件放在项目根目录下的 data 文件夹中。

目录结构示例

假设你的项目结构如下:

your_project/
    ├── your_app/
    │   ├── management/
    │   │   ├── commands/
    │   │       ├── import_customers.py
    │   ├── models.py
    │   ├── views.py
    │   ├── ...
    ├── data/
    │   ├── customers_reviews.xlsx
    ├── manage.py
    ├── ...

文件路径

在这种情况下,你的 Excel 文件路径应为 'data/customers_reviews.xlsx'。

修改 import_customers.py

确保你的管理命令正确读取文件:

import_customers.py

import pandas as pd
from django.core.management.base import BaseCommand
from your_app.models import Customer, Review
import os

class Command(BaseCommand):
    help = 'Import customers and reviews from an Excel file'

    def handle(self, *args, **kwargs):
        # Construct the file path
        base_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
        file_path = os.path.join(base_dir, 'data', 'customers_reviews.xlsx')

        # Load Excel file
        df = pd.read_excel(file_path)

        for index, row in df.iterrows():
            customer, created = Customer.objects.get_or_create(
                name=row.get('Customer Name', 'Unknown'),
                defaults={
                    'phone': row.get('Phone', ''),
                    'address': row.get('Address', '')
                }
            )
            Review.objects.create(
                customer=customer,
                review_text=row.get('Review Text', ''),
                sentiment=row.get('Sentiment', '')
            )
        self.stdout.write(self.style.SUCCESS('Successfully imported data from Excel'))

使用管理命令导入数据

  1. 将Excel文件放在项目根目录的 data 文件夹中。
  2. 运行管理命令来导入数据:
python manage.py import_customers

这样,Django将会从 data/customers_reviews.xlsx 文件中读取数据并导入数据库。确保文件路径正确无误,并且Excel文件的结构与代码中读取的字段名称匹配。

评价页面中显示初始评价信息

好的,我们可以直接在网页上显示Excel表格的数据,并实现分页功能。我们将通过Django视图读取Excel文件并将数据传递给模板进行渲染。

第一步:创建视图来读取Excel数据

首先,创建一个视图来读取Excel文件并将数据传递给模板。

views.py

import pandas as pd
from django.core.paginator import Paginator
from django.shortcuts import render
import os

def data_view(request):
    base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    file_path = os.path.join(base_dir, 'data', 'customers_reviews.xlsx')

    # Load Excel file
    df = pd.read_excel(file_path)

    # Convert DataFrame to list of dictionaries
    data_list = df.to_dict(orient='records')

    # Paginate data
    paginator = Paginator(data_list, 20)  # Show 20 items per page
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)

    return render(request, 'datas.html', {'page_obj': page_obj, 'columns': df.columns})

第二步:创建模板来渲染数据

接下来,创建一个模板来显示数据,并添加分页控件。

templates/datas.html

{% extends "base.html" %}

{% block title %}Data View{% endblock %}

{% block content %}
<section class="data-list">
    <h2>Data List</h2>
    <table>
        <thead>
            <tr>
                {% for column in columns %}
                <th>{{ column }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% for row in page_obj %}
            <tr>
                {% for value in row.values %}
                <td>{{ value }}</td>
                {% endfor %}
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <div class="pagination">
        <span class="step-links">
            {% if page_obj.has_previous %}
                <a href="?page=1">&laquo; first</a>
                <a href="?page={{ page_obj.previous_page_number }}">previous</a>
            {% endif %}

            <span class="current">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>

            {% if page_obj.has_next %}
                <a href="?page={{ page_obj.next_page_number }}">next</a>
                <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
            {% endif %}
        </span>
    </div>
</section>
{% endblock %}

第三步:更新URL配置

确保在urls.py中添加新的URL配置,以支持新的视图函数。

urls.py

from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
    path('data/', views.data_view, name='data_view'),
    # 其他路径...
]

第四步:运行服务器并访问页面

确保Django开发服务器正在运行,并访问/data/页面查看数据。

python manage.py runserver

访问http://localhost:8000/data/,你应该能够看到Excel表格的数据,每页显示20条,并带有分页控件。

通过这些步骤,你可以在网页上显示Excel表格的内容,并实现分页功能。如果还有任何问题或需要进一步调整,请告诉我。

更新模板中的URL名称以匹配URL配置中的名称:

base.html

htmlCopy code<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}CRM System{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/index.css' %}">
</head>
<body>
    <header>
        <h1>Customer Relationship Management System</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'index' %}">Home</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'data_view' %}">Datas</a></li>  <!-- 确保这里的name和urls.py中的name一致 -->
        </ul>
    </nav>
    <main>
        {% block content %}
        {% endblock %}
    </main>
    <footer>
        <p>&copy; 2024 Liu Feisheng. All rights reserved.</p>
    </footer>
</body>
</html>

项目虚拟环境

如果你没有使用虚拟环境,但想要查看当前系统中安装的 pip 软件包,可以使用以下方法:

查看当前安装的 pip 软件包

  1. 使用 pip list 命令:

    这个命令会列出当前 Python 环境中所有安装的 pip 软件包及其版本:

    sh pip list

  2. 使用 pip freeze 命令:

    这个命令会生成一个包含所有安装的 pip 软件包及其版本的文件,通常用于生成 requirements.txt 文件:

    sh pip freeze > requirements.txt

    生成的 requirements.txt 文件将包含所有当前安装的软件包及其版本。

创建新的虚拟环境并安装相同的

软件包

如果你想要创建一个新的虚拟环境并安装相同的软件包,可以按照以下步骤操作:

  1. 创建新的虚拟环境:

    sh python3 -m venv venv # 创建新的虚拟环境,venv 是虚拟环境的目录名

  2. 激活虚拟环境:

    在Linux或macOS上:

    sh source venv/bin/activate

    在Windows上:

    sh .\venv\Scripts\activate

  3. 安装 requirements.txt 中的软件包:

    使用之前生成的 requirements.txt 文件,在新的虚拟环境中安装所有必要的软件包:

    sh pip install -r requirements.txt

完整流程示例

  1. 查看当前系统中安装的 pip 软件包:

    sh pip freeze > requirements.txt

  2. 创建并激活新的虚拟环境:

    ```sh python3 -m venv venv source venv/bin/activate # Linux或macOS

    或者在Windows上

    .\venv\Scripts\activate ```

  3. 安装 requirements.txt 中的软件包:

    sh pip install -r requirements.txt

通过这些步骤,你可以查看当前系统中安装的所有 pip 软件包,并在新的虚拟环境中重新安装这些软件包。这样可以确保你在一个隔离的环境中运行你的 Django 项目,避免与系统其他项目的依赖冲突。

Django 项目持久化运行

要使用Gunicorn来实现Django应用的持久化运行,你可以按照以下步骤进行操作。Gunicorn是一个Python WSGI HTTP服务器,适用于UNIX,适合运行Django应用。

步骤1:安装Gunicorn

首先,你需要安装Gunicorn。可以使用pip来安装:

pip install gunicorn

步骤2:配置Gunicorn启动命令

你可以在Django项目的根目录下创建一个Gunicorn配置文件或直接使用命令行启动Gunicorn。

直接使用命令行启动

你可以使用以下命令来启动Gunicorn:

gunicorn your_project.wsgi:application --bind 0.0.0.0:8000

其中your_project是你的Django项目的名称。

创建Gunicorn配置文件(可选)

你可以创建一个Gunicorn配置文件来保存Gunicorn的配置。创建一个名为gunicorn_config.py的文件,并添加以下内容:

# gunicorn_config.py

bind = "0.0.0.0:8000"
workers = 3

然后使用以下命令启动Gunicorn:

gunicorn -c gunicorn_config.py your_project.wsgi:application

步骤3:配置Supervisor进行进程管理(可选)

为了确保Gunicorn在服务器重启时自动启动并保持运行状态,你可以使用Supervisor来管理Gunicorn进程。

安装Supervisor

你可以使用以下命令来安装Supervisor:

sudo apt-get install supervisor

创建Supervisor配置文件

在/etc/supervisor/conf.d/目录下创建一个新的Supervisor配置文件,例如your_project.conf:

sudo nano /etc/supervisor/conf.d/your_project.conf

然后在文件中添加以下内容:

[program:your_project]
command=/path/to/your/virtualenv/bin/gunicorn -c /path/to/your/gunicorn_config.py your_project.wsgi:application
directory=/path/to/your/project
user=your_user
autostart=true
autorestart=true
redirect_stderr=true
  • command:指向Gunicorn启动命令
  • directory:你的Django项目目录
  • user:运行Gunicorn的用户

重新加载Supervisor配置并启动Gunicorn

运行以下命令来重新加载Supervisor配置并启动Gunicorn:

sudo supervisorctl reread
sudo supervisorctl update
sudo supervisorctl start your_project

步骤4:配置Nginx进行反向代理(可选)

你可以使用Nginx来作为反向代理,将请求转发到Gunicorn。

安装Nginx

你可以使用以下命令来安装Nginx:

sudo apt-get install nginx

配置Nginx

在/etc/nginx/sites-available/目录下创建一个新的Nginx配置文件,例如your_project:

sudo nano /etc/nginx/sites-available/your_project

然后在文件中添加以下内容:

server {
    listen 80;
    server_name your_domain_or_IP;

    location = /favicon.ico { access_log off; log_not_found off; }
    location /static/ {
        root /path/to/your/project;
    }

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://127.0.0.1:8000;
    }
}

创建一个符号链接将配置文件链接到sites-enabled目录:

sudo ln -s /etc/nginx/sites-available/your_project /etc/nginx/sites-enabled

测试Nginx配置并重新加载Nginx:

sudo nginx -t
sudo systemctl restart nginx

通过这些步骤,你可以使用Gunicorn和Nginx来实现Django应用的持久化运行。如果还有任何问题或需要进一步调整,请告诉我。

asgiref==3.8.1 Django==5.0.6 et-xmlfile==1.1.0 gunicorn==22.0.0 numpy==2.0.0 openpyxl==3.1.4 packaging==24.1 pandas==2.2.2 python-dateutil==2.9.0.post0 pytz==2024.1 six==1.16.0 sqlparse==0.5.0 typing_extensions==4.12.2 tzdata==2024.1

静态文件处理

在Django项目中,通常有两种方式来管理静态文件:

  1. 项目级别的静态文件:放在项目的根目录中。
  2. 应用级别的静态文件:放在应用的静态文件夹中。

当前情况

根据你的文件树,static 文件夹同时出现在项目根目录和 customers 应用目录中。

建议

  1. 项目级别的静态文件:

    • 将 static 文件夹保留在项目根目录中。
  2. 应用级别的静态文件:

    • 将应用相关的静态文件保留在 customers/static 文件夹中。

具体步骤

  1. 确保在项目的根目录中有一个 static 文件夹,并将项目级别的静态文件放在其中。
project_root/
├── crm/
├── customers/
├── data/
├── db.sqlite3
├── manage.py
└── static/  # 项目级别的静态文件夹
    ├── css/
    │   └── index.css
    └── images/
  1. 保持应用级别的静态文件在 customers/static 文件夹中:
project_root/
├── crm/
├── customers/
│   ├── static/
│   │   └── css/
│   │       └── index.css
  1. 更新 settings.py 以包含项目级别的静态文件夹:
# settings.py

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

STATIC_URL = '/static/'

# Add this line to include the project-level static directory
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, 'static'),
]

最终文件树结构

project_root/
├── crm/
│   ├── __init__.py
│   ├── __pycache__/
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── customers/
│   ├── __init__.py
│   ├── __pycache__/
│   ├── admin.py
│   ├── apps.py
│   ├── forms.py
│   ├── management/
│   │   ├── __init__.py
│   │   └── commands/
│   │       ├── __init__ .py
│   │       └── import_customers.py
│   ├── migrations/
│   ├── models.py
│   ├── static/
│   │   └── css/
│   │       └── index.css
│   ├── templates/
│   │   ├── base.html
│   │   ├── customers/
│   │   │   ├── customer.html
│   │   │   ├── customer_form_1.html
│   │   │   ├── customers_1.html
│   │   │   ├── index_1.html
│   │   │   └── review_form.html
│   │   ├── customers.html
│   │   ├── datas.html
│   │   ├── index.html
│   │   ├── reports.html
│   │   ├── reviews.html
│   │   └── sentiment_analysis.html
│   ├── tests.py
│   └── views.py
├── data/
│   └── customers_reviews.xlsx
├── db.sqlite3
├── manage.py
└── static/
    ├── css/
    │   └── index.css
    └── images/

更新并测试

  1. 运行Django开发服务器:
python manage.py runserver
  1. 加载页面并验证静态文件是否正常工作。

通过上述调整,你可以确保静态文件的组织和管理更加清晰,并且可以更好地调试和部署项目。如果还有其他问题,请告诉我。

Datas.html信息更新

将excel数据导入到数据库中

为了提高数据加载的效率,可以将Excel数据导入到数据库中,并在访问 datas.html 页面时从数据库中读取数据,而不是每次都从Excel文件读取。以下是实现该功能的步骤:

1. 将Excel数据导入到数据库

可以创建一个Django管理命令来导入Excel数据。创建一个新的管理命令文件 import_data.py:

# customers/management/commands/import_data.py
import pandas as pd
from django.core.management.base import BaseCommand
from customers.models import CustomerReview

class Command(BaseCommand):
    help = 'Import customer review data from Excel'

    def handle(self, *args, **kwargs):
        file_path = 'data/customers_reviews.xlsx'
        df = pd.read_excel(file_path)

        for _, row in df.iterrows():
            CustomerReview.objects.create(
                review_time=row['评价时间'],
                review_tag=row['评价标签'],
                review_detail=row['评价详情'],
                star_rating=row['星级分'],
                flavor_rating=row['口味分'],
                environment_rating=row['环境分'],
                service_rating=row['服务分'],
                category_rating=row['品类分'],
                ingredient_rating=row['食材分'],
                value_for_money_rating=row['性价比分'],
                viewers=row['浏览人数'],
                city=row['城市'],
                store=row['评价门店'],
                store_meituan_id=row['门店美团ID'],
                group_buy_id=row['团购ID'],
                review_group_buy=row['评价团购'],
                review_source=row['评价来源'],
                user_nickname=row['用户昵称'],
                is_vip=row['是否vip'],
                user_level=row['用户等级'],
                reply_status=row['回复状态'],
                merchant_reply=row['商户回复内容'],
                merchant_reply_time=row['商户回复时间'],
                comment_content=row['盖楼内容']
            )
        self.stdout.write(self.style.SUCCESS('Data imported successfully'))

2. 创建数据模型

确保在 customers/models.py 中定义相应的数据模型 CustomerReview:

# customers/models.py
from django.db import models

class CustomerReview(models.Model):
    review_time = models.DateTimeField()
    review_tag = models.CharField(max_length=255, null=True, blank=True)
    review_detail = models.TextField()
    star_rating = models.FloatField(null=True, blank=True)
    flavor_rating = models.FloatField(null=True, blank=True)
    environment_rating = models.FloatField(null=True, blank=True)
    service_rating = models.FloatField(null=True, blank=True)
    category_rating = models.FloatField(null=True, blank=True)
    ingredient_rating = models.FloatField(null=True, blank=True)
    value_for_money_rating = models.FloatField(null=True, blank=True)
    viewers = models.IntegerField(null=True, blank=True)
    city = models.CharField(max_length=255, null=True, blank=True)
    store = models.CharField(max_length=255, null=True, blank=True)
    store_meituan_id = models.CharField(max_length=255, null=True, blank=True)
    group_buy_id = models.CharField(max_length=255, null=True, blank=True)
    review_group_buy = models.CharField(max_length=255, null=True, blank=True)
    review_source = models.CharField(max_length=255, null=True, blank=True)
    user_nickname = models.CharField(max_length=255, null=True, blank=True)
    is_vip = models.CharField(max_length=255, null=True, blank=True)
    user_level = models.CharField(max_length=255, null=True, blank=True)
    reply_status = models.CharField(max_length=255, null=True, blank=True)
    merchant_reply = models.TextField(null=True, blank=True)
    merchant_reply_time = models.DateTimeField(null=True, blank=True)
    comment_content = models.TextField(null=True, blank=True)

3. 更新视图以从数据库获取数据

在 views.py 中更新视图以从数据库读取数据:

# customers/views.py
from django.shortcuts import render
from django.core.paginator import Paginator
from .models import CustomerReview

def data_view(request):
    reviews = CustomerReview.objects.all()
    paginator = Paginator(reviews, 10)  # Show 10 reviews per page

    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    columns = [field.verbose_name for field in CustomerReview._meta.fields]

    context = {
        'page_obj': page_obj,
        'columns': columns
    }
    return render(request, 'datas.html', context)

4. 调整模板

在 datas.html 模板中,调整 row.values 为 Django 模型实例:

{% extends "base.html" %}

{% block title %}Data View{% endblock %}

{% block content %}
<section class="data-list">
    <h2>Data List</h2>
    <table>
        <thead>
            <tr>
                {% for column in columns %}
                <th>{{ column }}</th>
                {% endfor %}
            </tr>
        </thead>
        <tbody>
            {% for review in page_obj %}
            <tr>
                <td>{{ review.review_time }}</td>
                <td>{{ review.review_tag }}</td>
                <td>{{ review.review_detail }}</td>
                <td>{{ review.star_rating }}</td>
                <td>{{ review.flavor_rating }}</td>
                <td>{{ review.environment_rating }}</td>
                <td>{{ review.service_rating }}</td>
                <td>{{ review.category_rating }}</td>
                <td>{{ review.ingredient_rating }}</td>
                <td>{{ review.value_for_money_rating }}</td>
                <td>{{ review.viewers }}</td>
                <td>{{ review.city }}</td>
                <td>{{ review.store }}</td>
                <td>{{ review.store_meituan_id }}</td>
                <td>{{ review.group_buy_id }}</td>
                <td>{{ review.review_group_buy }}</td>
                <td>{{ review.review_source }}</td>
                <td>{{ review.user_nickname }}</td>
                <td>{{ review.is_vip }}</td>
                <td>{{ review.user_level }}</td>
                <td>{{ review.reply_status }}</td>
                <td>{{ review.merchant_reply }}</td>
                <td>{{ review.merchant_reply_time }}</td>
                <td>{{ review.comment_content }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <div class="pagination">
        <span class="step-links">
            {% if page_obj.has_previous %}
                <a href="?page=1">&laquo; first</a>
                <a href="?page={{ page_obj.previous_page_number }}">previous</a>
            {% endif %}

            <span class="current">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>

            {% if page_obj.has_next %}
                <a href="?page={{ page_obj.next_page_number }}">next</a>
                <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
            {% endif %}
        </span>
    </div>
</section>
{% endblock %}

通过以上步骤,你将Excel中的数据导入到数据库中,并在访问 datas.html 页面时从数据库读取数据,而不是每次从Excel文件读取,从而提高了数据加载的效率。

数据导入

运行数据导入命令:


python manage.py import_data

确认数据库迁移成功

确保你已经运行了所有的数据库迁移:

python manage.py makemigrations
python manage.py migrate

正常显示底部信息及翻页

为了确保 footer 仅在页面内容滚动到底部时才显示在页面底部,而不是固定在页面底部,我们需要调整 CSS 使其采用常规的文档流布局而不是固定定位。

下面是调整后的 base.html 和 CSS 内容:

修改后的 base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>{% block title %}CRM System{% endblock %}</title>
    {% load static %}
    <link rel="stylesheet" href="{% static 'css/index.css' %}">
</head>
<body>
    <header>
        <h1>Customer Relationship Management System</h1>
    </header>
    <nav>
        <ul>
            <li><a href="{% url 'index' %}">Home</a></li>
            <li><a href="{% url 'data_view' %}">Datas</a></li>
            <li><a href="{% url 'customers' %}">Customers</a></li>
            <li><a href="{% url 'reviews' %}">Reviews</a></li>
            <li><a href="{% url 'sentiment_analysis' %}">Sentiment Analysis</a></li>
            <li><a href="{% url 'reports' %}">Reports</a></li>
        </ul>
    </nav>
    <main>
        {% block content %}
        {% endblock %}
    </main>
    <footer>
        <p>&copy; 2024 Liu Feisheng. All rights reserved.</p>
    </footer>
</body>
</html>

修改后的 CSS

body {
    font-family: 'Helvetica Neue', Arial, sans-serif;
    margin: 0;
    padding: 0;
    background-color: #f9f9f9;
    color: #333;
    line-height: 1.6;
    display: flex;
    flex-direction: column;
    min-height: 100vh;
}

header {
    background-color: #4CAF50;
    color: #fff;
    padding: 1rem 0;
    text-align: center;
}

nav ul {
    list-style: none;
    padding: 0;
    background-color: #333;
    display: flex;
    justify-content: center;
    margin: 0;
}

nav ul li {
    margin: 0 1rem;
}

nav ul li a {
    color: #fff;
    text-decoration: none;
    padding: 0.5rem 1rem;
    display: block;
}

nav ul li a:hover {
    background-color: #555;
}

main {
    padding: 2rem;
    max-width: 800px;
    margin: 0 auto;
    flex: 1;
}

h2, h3 {
    color: #4CAF50;
}

.intro, .purpose, .modules, .data-source {
    margin-bottom: 2rem;
}

.intro img, .modules img, .data-source img {
    width: 100%;
    height: auto;
    border-radius: 8px;
    margin-bottom: 1rem;
}

ul {
    text-align: left;
    display: inline-block;
    margin: 1rem auto;
}

footer {
    text-align: center;
    padding: 1rem 0;
    background-color: #333;
    color: #fff;
}

@media (max-width: 768px) {
    nav ul {
        flex-direction: column;
    }

    nav ul li {
        margin: 0.5rem 0;
    }

    main {
        padding: 1rem;
    }

    h2, h3 {
        font-size: 1.5rem;
    }

    ul {
        width: 100%;
    }
}

@media (max-width: 480px) {
    header h1 {
        font-size: 1.5rem;
    }

    nav ul li a {
        padding: 0.5rem;
    }

    main {
        padding: 0.5rem;
    }

    h2, h3 {
        font-size: 1.2rem;
    }
}

解释

  • 将 body 设置为 display: flex,并使用 flex-direction: column 使其子元素垂直排列。
  • 将 main 部分设置为 flex: 1,使其占据剩余的垂直空间,从而确保 footer 在页面内容不满屏幕时保持在页面底部,但不固定在页面底部。

通过以上调整,footer 仅在页面内容滚动到底部时才显示在页面底部。如果你有其他问题或需要进一步调整,请告诉我。

Custom页面更新

  • 创建客户管理的视图和表单,使用Django的通用视图(Generic Views)简化开发。
  • customer的数据直接读自于数据库
  • 如果前面datas已经有了数据,那么新的customers.html只需要从db.sqlite3数据库读取数据并显示 就可以了
  • 'user_nickname', 'is_vip', 'user_level', 'review_time', 'review_tag'

为了从数据库中提取 user_nickname, is_vip, user_level, review_time, 和 review_tag 这5个字段信息,我们需要确保在视图函数中正确查询这些字段,并将数据传递给模板进行显示。

修改 views.py

确保视图函数正确获取 Customer 数据,并传递给模板:

from django.shortcuts import render
from .models import Customer
from django.core.paginator import Paginator

def customers(request):
    customers = CustomerReview.objects.all()  # 获取CustomerReview模型的数据
    paginator = Paginator(customers, 10)  # 每页显示10条记录
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, 'customers.html', {'customers': page_obj})

修改 models.py

确保视图函数正确获取 Customer 数据,并传递给模板:

class Customer(models.Model):
    user_nickname = models.CharField(max_length=255, null=True, blank=True)
    is_vip = models.CharField(max_length=255, null=True, blank=True)
    user_level = models.CharField(max_length=255, null=True, blank=True)
    review_time = models.DateTimeField()
    review_tag = models.CharField(max_length=255, null=True, blank=True)

修改 customers.html

确保模板正确显示 Customer 数据,并实现分页功能:

{% extends "base.html" %}

{% block title %}Customer Information{% endblock %}

{% block content %}

<section class="customer-list">
    <h2>Customer Information</h2>
    <table>
        <thead>
            <tr>
                <th>User ID</th>
                <th>User Nickname</th>
                <th>Is VIP</th>
                <th>User Level</th>
                <th>Review Time</th>
                <th>Review Tag</th>
            </tr>
        </thead>
        <tbody>
            {% if customers %}
                {% for customer in customers %}
                    <tr>
                        <td>{{ customer.id }}</td>
                        <td>{{ customer.user_nickname }}</td>
                        <td>{{ customer.is_vip }}</td>
                        <td>{{ customer.user_level }}</td>
                        <td>{{ customer.review_time }}</td>
                        <td>{{ customer.review_tag }}</td>
                    </tr>
                {% endfor %}
            {% else %}
                <tr>
                    <td colspan="5">No customer data available.</td>
                </tr>
            {% endif %}
        </tbody>
    </table>
    <div class="pagination">
        <span class="step-links">
            {% if customers.has_previous %}
                <a href="?page=1">&laquo; first</a>
                <a href="?page={{ customers.previous_page_number }}">previous</a>
            {% endif %}

            <span class="current">
                Page {{ customers.number }} of {{ customers.paginator.num_pages }}.
            </span>

            {% if customers.has_next %}
                <a href="?page={{ customers.next_page_number }}">next</a>
                <a href="?page={{ customers.paginator.num_pages }}">last &raquo;</a>
            {% endif %}
        </span>
    </div>
</section>
{% endblock %}

确认 urls.py

确保 URL 配置正确指向视图函数:

from django.urls import path
from . import views

urlpatterns = [
    path('customers/', views.customers, name='customers'),
]

通过这些修改,customers.html 页面应该能够正确显示从数据库中提取的 user_nickname, is_vip, user_level, review_time, 和 review_tag 这5个字段信息,并实现分页功能。请确认这些文件的内容,并重新启动 Django 服务器,检查功能是否正常。如果还有问题,请告诉我详细情况,我将继续帮助你进行调试。

Reviews页面更新

  • 创建评价管理的视图和表单,使用Django的通用视图(Generic Views)简化开发。
  • 如果前面datas已经有了数据,那么新的customers.html只需要从db.sqlite3数据库读取数据并显示 就可以了

修改 views.py

确保视图函数正确获取 Customer 数据,并传递给模板:

from django.shortcuts import render
from .models import Customer
from django.core.paginator import Paginator

def reviews(request):
    reviews = CustomerReview.objects.all()
    paginator = Paginator(reviews, 10)  # Show 10 reviews per page

    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    return render(request, 'reviews.html', {'page_obj': page_obj})

修改 models.py

确保视图函数正确获取 Customer 数据,并传递给模板:

class Review(models.Model):
    customer = models.CharField(max_length=255, null=True, blank=True)
    review_detail = models.TextField()
    review_time = models.DateTimeField()

修改 reviews.html

确保模板正确显示 数据,并实现分页功能:

{% extends "base.html" %}

{% block title %}Review Management{% endblock %}

{% block content %}
<section class="review-list">
    <h2>Review List</h2>
    <table>
        <thead>
            <tr>
                <th>ID</th>
                <th>Customer</th>
                <th>Review</th>
                <th>Time</th>
            </tr>
        </thead>
        <tbody>
            {% for review in page_obj %}
            <tr>
                <td>{{ review.id }}</td>
                <td>{{ review.customer }}</td>
                <td>{{ review.review_detail }}</td>
                <td>{{ review.review_time }}</td>
            </tr>
            {% endfor %}
        </tbody>
    </table>
    <div class="pagination">
        <span class="step-links">
            {% if page_obj.has_previous %}
                <a href="?page=1">&laquo; first</a>
                <a href="?page={{ page_obj.previous_page_number }}">previous</a>
            {% endif %}

            <span class="current">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>

            {% if page_obj.has_next %}
                <a href="?page={{ page_obj.next_page_number }}">next</a>
                <a href="?page={{ page_obj.paginator.num_pages }}">last &raquo;</a>
            {% endif %}
        </span>
    </div>
</section>
{% endblock %}

确认 urls.py

Sentiment Analysis页面更新

Reported页面更新

autodraw.ipynb, 绘制框架图、模型图

draw.ipynb, 绘制了实验结果各种折线图、雷达图等

20241117部署到本地Deepin系统

  • 首先在github下载项目,然后在项目中创建python虚拟环境 python -m venv venv
  • source venv/bin/active 激活虚拟环境,安装相应的库,pip install -r requirements.txt
  • 在当前项目运行gunicorn crm.wsgi:application --bind 0.0.0.0:8082,绑定到8082端口,本地localhost:8082就能正常访问crm系统
  • 设置开机自启动
  1. 要使Django项目在开机后自动运行,您可以使用systemd服务。首先,创建一个systemd服务文件:

bash

bash sudo vim /etc/systemd/system/crm.service

然后添加以下内容(根据您的项目路径和需求进行调整):

ini

```ini [Unit] Description=My Django CRM Project, for doctor article

[Service] Type=simple User=fei WorkingDirectory=/usr/local/mycrm ExecStart=/usr/local/mycrm/venv/bin/gunicorn -w 4 -b 0.0.0.0:8082 crm.wsgi:application

[Install] WantedBy=multi-user.target ```

这将创建一个名为crm.service的服务,用于在系统启动时自动启动您的Django项目。

注意: 低于1024的端口号,system运行时容易出错 ,所以从原来的82端口改为8082

  1. 启用并启动服务: 使用以下命令启用并启动您的服务:

bash

bash sudo systemctl enable crm sudo systemctl start crm

这将设置服务以在每次启动时自动运行,并立即启动服务。

20241118运行时出现错误 ,systmctl启动出错,只能用命令启动

20241221部署到阿里云服务器

  • 首先在github下载项目,把原有的venv删除,然后在项目中创建python虚拟环境 python -m venv venv
  • source venv/bin/active 激活虚拟环境,安装相应的库,pip install -r requirements.txt
  • 在当前环境运行 python manage.py runserver 0.0.0.0:83,本地localhost:83就能正常访问crm系统
  • 设置开机自启动
  1. 要使Django项目在开机后自动运行,您可以使用systemd服务。首先,创建一个systemd服务文件:

bash

bash sudo vim /etc/systemd/system/mycrm.service

然后添加以下内容(根据您的项目路径和需求进行调整):

ini

```ini [Unit] Description=Django Application After=network.target

[Service] User=root Group=root WorkingDirectory=/usr/local/mycrm ExecStart=/usr/local/mycrm/venv/bin/python manage.py runserver 0.0.0.0:83 Restart=always

[Install] WantedBy=multi-user.target ```

这将创建一个名为mycrm.service的服务,用于在系统启动时自动启动您的Django项目。

  1. 启用并启动服务: 使用以下命令启用并启动您的服务:

bash

bash sudo systemctl enable mycrm sudo systemctl start mycrm

这将设置服务以在每次启动时自动运行,并立即启动服务。