终于到了最激动人心的时刻!这几天看着蠢蠢的API界面已经要吐了。这次我们要把客户模块和之前的注册/登录/用户界面搞到一起。
之前我们的注册/登录/用户界面是视图和模板,也就是views.py和templates.py进行页面设计和逻辑处理的,现在我们有DRF的API了,就可以纯粹的使用JSON数据接口的。
我们现在需要在视图里调用我们自己写得API,来实现类似的前后端分离的逻辑了。
之前我们已经写了CustomerSet类,算是实现了后端逻辑。现在我们需要写一个前端了逻辑来展示客户列表(伟大的GPT之神啊,请听从我的呼唤,帮我写个前端界面吧~)
@login_required
def customer_list_view(request):
api_url = request.build_absolute_uri('/api/customers/')
session_id = request.session.session_key
cookies = {'sessionid': session_id}
try:
response = requests.get(api_url, cookies=cookies)
response.raise_for_status()
customers = response.json()
except requests.exceptions.RequestException as e:
print(f"API 请求失败:{e}")
customers = []
return render(request, 'customer/customer_list.html',
{'customers':customers})
然后前端我们单独做一个客户列表的展示,并修改下base.html,在里面加入客户这个菜单选项
base.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}喵喵CRM{% endblock %}</title>
<style>
body {
font-family: Arial, sans-serif;
margin: 0;
padding: 0;
background-color: #f4f4f4;
color: #333;
}
header {
background-color: #333;
color: white;
padding: 10px 0;
text-align: center;
}
nav a {
color: #fff;
margin: 0 15px;
text-decoration: none;
}
nav a:hover {
text-decoration: underline;
}
hr {
border: 0;
border-top: 1px solid #ddd;
margin: 20px 0;
}
main {
padding: 20px;
}
.messages {
list-style-type: none;
padding: 0;
margin: 0;
}
.messages li {
background-color: #e1f7d5;
color: #4CAF50;
padding: 10px;
margin-bottom: 10px;
}
</style>
</head>
<body>
<header>
<h1>喵喵CRM</h1>
<nav>
{% if request.user.is_authenticated %}
欢迎,{{ request.user.username }} |
<a href="{% url 'home' %}">主页</a> |
<a href="{% url 'customer_list' %}">我的客户</a> |
<a href="{% url 'logout' %}">退出</a>
{% else %}
<a href="{% url 'login' %}">登录</a> |
<a href="{% url 'register' %}">注册</a>
{% endif %}
</nav>
</header>
{% if messages %}
<ul class="messages">
{% for msg in messages %}
<li>{{ msg }}</li>
{% endfor %}
</ul>
{% endif %}
<main>
{% block content %}{% endblock %}
</main>
</body>
</html>
customer_list.html
{% extends "customer/base.html" %}
{% block title %}我的客户 - 喵喵CRM{% endblock %}
{% block content %}
<div style="max-width: 900px; margin: 0 auto; padding: 20px;">
<h2 style="text-align: center; margin-bottom: 20px;">我的客户列表</h2>
<table style="width: 100%; border-collapse: collapse;">
<thead style="background-color: #333; color: white;">
<tr>
<th style="padding: 12px; text-align: left;">姓名</th>
<th style="padding: 12px; text-align: left;">邮箱</th>
<th style="padding: 12px; text-align: left;">电话</th>
<th style="padding: 12px; text-align: left;">负责人</th>
</tr>
</thead>
<tbody>
{# 'customers'就是我们从view的context里传过来的列表 #}
{% for customer in customers %}
<tr style="border-bottom: 1px solid #ddd;">
<td style="padding: 12px;">{{ customer.name }}</td>
<td style="padding: 12px;">{{ customer.email|default:'--' }}</td>
<td style="padding: 12px;">{{ customer.phone|default:'--' }}</td>
{# 还记得吗?我们在Serializer里把owner变成了用户名字符串 #}
<td style="padding: 12px;">{{ customer.owner }}</td>
</tr>
{% empty %}
{# 如果customers列表是空的,就显示这个 #}
<tr>
<td colspan="4" style="text-align: center; padding: 20px; color: #777;">
您还没有客户,快去添加第一个客户吧!
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% endblock %}
OK,搞定,上述就是一个简单的前后端分离逻辑,同时我们把客户列表的展示融入了之前的注册/登录/用户界面里。

太酷了不是吗,哈哈哈。
不过还不太够,我们的客户增删改查呢?怎么如今只有一个孤零零的客户列表展示放在界面上?而要实现网页端实时的增删改查,就需要另一个前端工具javascript。此处我们不学习JS,但是我们得了解JS到底能做啥。JS可以监听网页上的一些操作,比如监听新增客户按钮,点击后就弹出对话框来输入客户信息;还可以不刷新页面的情况下与服务器通信。
算了,头有点麻,明天在搞。