返回顶部

Django web框架实现nacos【多配置】修改

Django web框架实现nacos【多配置】修改

基于上面一个博客进行功能升级优化,在实际场景中一般会有多个配置需要同时进行修改,上章节功能就不足满足使用了,在此基础上进行功能优化同时修改多个配置进行提交表单。

1. 安装依赖

pip install nacos-sdk-python PyYAML

 

2. 创建类修改Nacos配置nacos_settings.py

在 Django 项目中使用 Nacos 需要进行一些配置。您需要在nacos_settings.py文件中添加以下配置,.

NACOS_SERVERS 是 Nacos 服务器的地址,NAMESPACE 是命名空间,DATA_ID 是要获取和更新的配置文件的 ID,GROUP 是配置文件所属的分组

# Create your views here.

import redis


def delete_redis_key(request):
    # 连接 Redis
    r = redis.Redis(host='172.31.0.8', port=6379, db=0, password='Common1qaz@WSX2020')

    id = request.GET.get('id')
    print(id)

    # 获取要删除的 Redis key
    key = request.GET.get('key', '')

    # 删除 Redis key
    r.delete(key)

    # # 获取所有符合条件的 key
    # # keys = r.keys('prefix:*') #prefix:* 表示需要删除的 key 的前缀
    # keys = r.keys('my_key*')  # 匹配所有my_key*的key,my_key* 表示需要删除的 key 的前缀
    #
    # # 批量删除 key
    # if keys:
    #     r.delete(*keys)

    # 返回结果页面,渲染模版文件
    context = {'deleted': True}
    return render(request, 'result.html', context)

# # 使用NacosConfig类获取和修改配置信息 【单个配置】
# from myweb1.nacos_settings import NACOS_SERVERS, NAMESPACE, DATA_ID, GROUP
# from django.http import HttpResponse
# from django.shortcuts import render
# from django.views.decorators.csrf import csrf_exempt
# from myweb1.nacos_settings import NacosConfig
# import yaml
#
# nacos_config = NacosConfig(server_addr=NACOS_SERVERS, namespace=NAMESPACE, data_id=DATA_ID, group=GROUP)
#
# @csrf_exempt
# def get_config(request):
#     # #显示配置文件
#     # content = nacos_config.get_config()
#     # return HttpResponse(content)
#
#     # yaml格式的显示配置文件
#     content = nacos_config.get_config()
#     if isinstance(content, bytes):
#         str_content = content.decode()
#     else:
#         str_content = content
#     dict_content = yaml.load(str_content, Loader=yaml.FullLoader)
#     yaml_content = yaml.dump(dict_content)
#     return render(request, 'config.html', {'yaml_content': yaml_content})
#
# @csrf_exempt
# def set_config(request):
#     if request.method == 'POST':
#         content = request.POST.get('content')
#         if content is None or content.strip() == '':
#             return HttpResponse('Error: content is empty')
#         print('Received content:', content)  # 输出日志信息
#         config = yaml.safe_load(nacos_config.get_config())
#         config['SECRET_KEY'] = content
#         success = nacos_config.set_config(yaml.dump(config))
#         return HttpResponse(success)
#     else:
#         return render(request, 'set_config.html')


## # 使用NacosConfig类获取和修改配置信息【多个配置】
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from myweb1.nacos_settings import  NACOS_SERVERS, NAMESPACE, DATA_ID, GROUP
from nacos import NacosClient
import yaml
from django import forms

#定义一个Django表单类ConfigForm,它继承自forms.Form。该表单类包含四个字段:secret_key、allowed_hosts、debug和password。
# secret_key是一个字符型字段,用于存储Django应用程序的秘密密钥。
# allowed_hosts是一个字符型字段,用于存储Django应用程序允许访问的主机列表。
# debug是一个字符型字段,用于存储Django应用程序的调试模式设置。
# password是一个字符型字段,用于存储密码,并使用密码输入小部件进行输入。
#这些字段将被用于创建HTML表单,并且在提交表单时,这些字段的值将被包含在请求中。您可以在视图函数中使用这些值来更新Nacos配置或执行其他操作。
class ConfigForm(forms.Form):
    secret_key = forms.CharField(label='Secret Key', max_length=100)
    allowed_hosts = forms.CharField(label='Allowed Hosts', max_length=100)
    debug = forms.CharField(label='DEBUG', max_length=100)
    password = forms.CharField(label='Password', widget=forms.PasswordInput)

# 在Django中提交一个修改配置的表单,可以创建一个视图函数,该函数将处理POST请求,并将表单数据保存回Nacos
def config_form(request):
    #获取当前配置
    nacos_client = NacosClient(server_addresses=NACOS_SERVERS, namespace=NAMESPACE)
    current_config = yaml.safe_load(nacos_client.get_config(DATA_ID,GROUP))

    if request.method == 'POST':
        #处理表单提交
        current_config['DATABASES']['default']['HOST'] = request.POST['host']
        current_config['DATABASES']['default']['PORT'] = request.POST['port']
        current_config['DATABASES']['default']['USER'] = request.POST['user']
        current_config['DATABASES']['default']['PASSWORD'] = request.POST.get('password')
        current_config['SECRET_KEY'] = request.POST['secret_key']
        current_config['DEBUG'] = request.POST['debug']
        current_config['ALLOWED_HOSTS'] = [h.strip() for h in request.POST['allowed_hosts'].split(',')]

        #将更新后的配置保存回Nacos
        content = yaml.dump(current_config)
        nacos_client.publish_config(data_id=DATA_ID, group=GROUP, content=content)

        #重定向到成功页面
        return HttpResponseRedirect('/myweb1/config/success/')
    else:
        #显示表单页面
        context = {
            'host': current_config['DATABASES']['default']['HOST'],
            'port': current_config['DATABASES']['default']['PORT'],
            'user': current_config['DATABASES']['default']['USER'],
            'password': current_config['DATABASES']['default']['PASSWORD'],
            'secret_key': current_config['SECRET_KEY'],
            'debug': current_config['DEBUG'],
            'allowed_hosts': ','.join(current_config['ALLOWED_HOSTS']),
        }
        return render(request, 'config_form.html', context)

def set_config(request):
    #处理表单提交
    nacos_client = NacosClient(server_addresses=NACOS_SERVERS, namespace=NAMESPACE)
    current_config['DATABASES']['default']['HOST'] = request.POST['host']
    current_config['DATABASES']['default']['PORT'] = request.POST['port']
    current_config['DATABASES']['default']['USER'] = request.POST['user']
    current_config['DATABASES']['default']['PASSWORD'] = request.POST.get['password']
    content = yaml.dump(current_config)
    nacos_client.set_config(DATA_ID, GROUP, content)

    #重定向到成功页面
    return HttpResponseRedirect('myweb1/config/success/')

def config_seccess(request):
    #获取更新后的配置
    nacos_client = NacosClient(server_addresses=NACOS_SERVERS, namespace=NAMESPACE)
    updated_config = yaml.safe_load(nacos_client.get_config(DATA_ID, GROUP))

    ### 将yaml配置转换为字符串并返回

    #设置更新后的配置URL
    updated_config_url = '/config/success/'

    #返回包含更新后的配置的html页面,yaml配置显示在当前页面,不下载
    context = {'config': yaml.dump(updated_config)}
    return render(request, 'config_success.html', context)

    #会下载修改后的yaml文件
    # content = yaml.dump(updated_config)
    # response = HttpResponse(content, content_type='text/plain')
    # response['Content-Disposition'] = 'attachment; filename="config.yaml"'
    # return response

3. 创建模板文件

在Django项目中创建一个名为more_config.html的模板文件,用于显示将要修改的配置项和其新值的表单

模板文件包含一个表单,用于提交新的配置值

模版文件目录: myproject/myapp/templates/

a. more_config.html

### ###  myproject/myapp/templates/more_config.html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Set Config</title>
</head>
<body>
    <h1>Set Config</h1>
    <form method="post">
        {% csrf_token %}
        <label for="secret_key">SECRET_KEY:</label>
        <input type="text" name="secret_key" id="secret_key">
        <br><br>
        <label for="db_name">DATABASE NAME:</label>
        <input type="text" name="db_name" id="db_name">
        <br><br>
        <label for="db_user">DATABASE USER:</label>
        <input type="text" name="db_user" id="db_user">
        <br><br>
        <label for="db_password">DATABASE PASSWORD:</label>
        <input type="password" name="db_password" id="db_password">
        <br><br>
        <label for="db_host">DATABASE HOST:</label>
        <input type="text" name="db_host" id="db_host">
        <br><br>
        <label for="db_port">DATABASE PORT:</label>
        <input type="text" name="db_port" id="db_port">
        <br><br>
        <input type="submit" value="Submit">
    </form>
</body>
</html>

 

b. config_form.html

config_form.html 页面示例,它包含一个表单,允许用户修改数据库配置。您可以将其保存为 templates/config_form.html 文件.

在 config_form 视图函数中,我们将 updated_config_url 添加到上下文中,以便它可以在模板中使用。在 config_success 视图函数中,我们将返回一个文件下载响应,并在其中设置文件名为 config.yaml。最后,在 config_form.html 页面中,我们使用 updated_config_url 变量创建一个链接,以便用户可以查看更新后的配置

添加了两个额外的输入框,一个用于修改 SECRET_KEY,另一个用于修改 ALLOWED_HOSTS。我们使用 value 属性来设置输入框的默认值,并使用 name 属性来设置输入框的名称,以便在表单提交时能够获取这些值。

 

请注意,在表单中包含了一个 CSRF 令牌,以防止跨站点请求伪造攻击。这个令牌可以通过使用 Django 模板标记 {% csrf_token %} 来生成。

 

如果您需要更多关于 Django 表单的信息,请参阅 Django 官方文档: https://docs.djangoproject.com/en/3.2/topics/forms/

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>修改数据库配置</title>
</head>
<body>
    <h1>修改数据库配置</h1>
<!--    https://docs.djangoproject.com/en/3.2/topics/forms/ -->
    <form method="post">
        {% csrf_token %}
        <p>
            <label for="id_host">主机名:</label>
            <input type="text" name="host" id="id_host" value="{{ host }}">
        </p>
        <p>
            <label for="id_port">端口号:</label>
            <input type="text" name="port" id="id_port" value="{{ port }}">
        </p>
        <p>
            <label for="id_user">用户名:</label>
            <input type="text" name="user" id="id_user" value="{{ user }}">
        </p>
        <p>
            <label for="id_password">密码:</label>
            <input type="password" name="password" id="id_password" value="{{ password }}">
        </p>
        <p>
            <label for="id_secret_key">Secret Key:</label>
            <input type="text" name="secret_key" id="id_secret_key" value="{{ secret_key }}">
        </p>
        <p>
            <label for="id_debug">DEBUG:</label>
            <input type="text" name="debug" id="id_debug" value="{{ debug }}">
        </p>
        <p>
            <label for="id_allowed_hosts">Allowed Hosts:</label>
            <input type="text" name="allowed_hosts" id="id_allowed_hosts" value="{{ allowed_hosts }}">
         </p>
        <button type="submit">保存</button>
    </form>

    {% if updated_config_url %}
    <p><a href="{{ updated_config_url }}">查看更新后的配置</a></p>
    {% endif %}
</body>
</html>

c. config_success.html

在 config_success 视图函数中,我们获取更新后的配置并将其传递给 config_success.html 模板.

使用了 <pre> 标签来显示 YAML 配置。这可以保留原始格式并使其易于阅读

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>配置已保存</title>
</head>
<body>
    <h1>配置已保存</h1>
    <p>您的配置已成功保存到 Nacos 中。</p>
    <h2>更新后的配置:</h2>
    <pre>{{ config }}</pre>
    <p><a href="/myapp/config/">返回配置页面</a></p>
</body>
</html>

 

4. 视图配置和修改Nacos配置

在Django视图中使用NacosConfig类获取和修改Nacos配置,并渲染more_config.html模板.

首先从POST请求中获取新的配置值,然后将它们存储在一个字典中。接下来,我们使用yaml.safe_load将当前配置解析为Python对象,然后使用字典的update()方法将新的配置值合并到当前配置中。最后,我们使用yaml.dump将更新后的配置对象转换为YAML字符串,并将其传递给NacosConfig类的set_config方法。

先获取当前配置,并在表单提交时更新它。然后,我们将更新后的配置保存回 Nacos,并重定向到成功页面。如果请求方法是 GET,则显示表单页面,并将当前配置的值用作表单字段的默认值。

### ### mysite/myweb1/views.py

# Create your views here.

import redis


def delete_redis_key(request):
    # 连接 Redis
    r = redis.Redis(host='172.31.0.8', port=6379, db=0, password='Common1qaz@WSX2020')

    id = request.GET.get('id')
    print(id)

    # 获取要删除的 Redis key
    key = request.GET.get('key', '')

    # 删除 Redis key
    r.delete(key)

    # # 获取所有符合条件的 key
    # # keys = r.keys('prefix:*') #prefix:* 表示需要删除的 key 的前缀
    # keys = r.keys('my_key*')  # 匹配所有my_key*的key,my_key* 表示需要删除的 key 的前缀
    #
    # # 批量删除 key
    # if keys:
    #     r.delete(*keys)

    # 返回结果页面,渲染模版文件
    context = {'deleted': True}
    return render(request, 'result.html', context)

# # 使用NacosConfig类获取和修改配置信息 【单个配置】
# from myweb1.nacos_settings import NACOS_SERVERS, NAMESPACE, DATA_ID, GROUP
# from django.http import HttpResponse
# from django.shortcuts import render
# from django.views.decorators.csrf import csrf_exempt
# from myweb1.nacos_settings import NacosConfig
# import yaml
#
# nacos_config = NacosConfig(server_addr=NACOS_SERVERS, namespace=NAMESPACE, data_id=DATA_ID, group=GROUP)
#
# @csrf_exempt
# def get_config(request):
#     # #显示配置文件
#     # content = nacos_config.get_config()
#     # return HttpResponse(content)
#
#     # yaml格式的显示配置文件
#     content = nacos_config.get_config()
#     if isinstance(content, bytes):
#         str_content = content.decode()
#     else:
#         str_content = content
#     dict_content = yaml.load(str_content, Loader=yaml.FullLoader)
#     yaml_content = yaml.dump(dict_content)
#     return render(request, 'config.html', {'yaml_content': yaml_content})
#
# @csrf_exempt
# def set_config(request):
#     if request.method == 'POST':
#         content = request.POST.get('content')
#         if content is None or content.strip() == '':
#             return HttpResponse('Error: content is empty')
#         print('Received content:', content)  # 输出日志信息
#         config = yaml.safe_load(nacos_config.get_config())
#         config['SECRET_KEY'] = content
#         success = nacos_config.set_config(yaml.dump(config))
#         return HttpResponse(success)
#     else:
#         return render(request, 'set_config.html')


## # 使用NacosConfig类获取和修改配置信息【多个配置】
from django.shortcuts import render
from django.http import HttpResponseRedirect, HttpResponse
from myweb1.nacos_settings import  NACOS_SERVERS, NAMESPACE, DATA_ID, GROUP
from nacos import NacosClient
import yaml
from django import forms

#定义一个Django表单类ConfigForm,它继承自forms.Form。该表单类包含四个字段:secret_key、allowed_hosts、debug和password。
# secret_key是一个字符型字段,用于存储Django应用程序的秘密密钥。
# allowed_hosts是一个字符型字段,用于存储Django应用程序允许访问的主机列表。
# debug是一个字符型字段,用于存储Django应用程序的调试模式设置。
# password是一个字符型字段,用于存储密码,并使用密码输入小部件进行输入。
#这些字段将被用于创建HTML表单,并且在提交表单时,这些字段的值将被包含在请求中。您可以在视图函数中使用这些值来更新Nacos配置或执行其他操作。
class ConfigForm(forms.Form):
    secret_key = forms.CharField(label='Secret Key', max_length=100)
    allowed_hosts = forms.CharField(label='Allowed Hosts', max_length=100)
    debug = forms.CharField(label='DEBUG', max_length=100)
    password = forms.CharField(label='Password', widget=forms.PasswordInput)

# 在Django中提交一个修改配置的表单,可以创建一个视图函数,该函数将处理POST请求,并将表单数据保存回Nacos
def config_form(request):
    #获取当前配置
    nacos_client = NacosClient(server_addresses=NACOS_SERVERS, namespace=NAMESPACE)
    current_config = yaml.safe_load(nacos_client.get_config(DATA_ID,GROUP))

    if request.method == 'POST':
        #处理表单提交
        current_config['DATABASES']['default']['HOST'] = request.POST['host']
        current_config['DATABASES']['default']['PORT'] = request.POST['port']
        current_config['DATABASES']['default']['USER'] = request.POST['user']
        current_config['DATABASES']['default']['PASSWORD'] = request.POST.get('password')
        current_config['SECRET_KEY'] = request.POST['secret_key']
        current_config['DEBUG'] = request.POST['debug']
        current_config['ALLOWED_HOSTS'] = [h.strip() for h in request.POST['allowed_hosts'].split(',')]

        #将更新后的配置保存回Nacos
        content = yaml.dump(current_config)
        nacos_client.publish_config(data_id=DATA_ID, group=GROUP, content=content)

        #重定向到成功页面
        return HttpResponseRedirect('/myweb1/config/success/')
    else:
        #显示表单页面
        context = {
            'host': current_config['DATABASES']['default']['HOST'],
            'port': current_config['DATABASES']['default']['PORT'],
            'user': current_config['DATABASES']['default']['USER'],
            'password': current_config['DATABASES']['default']['PASSWORD'],
            'secret_key': current_config['SECRET_KEY'],
            'debug': current_config['DEBUG'],
            'allowed_hosts': ','.join(current_config['ALLOWED_HOSTS']),
        }
        return render(request, 'config_form.html', context)

def set_config(request):
    #处理表单提交
    nacos_client = NacosClient(server_addresses=NACOS_SERVERS, namespace=NAMESPACE)
    current_config['DATABASES']['default']['HOST'] = request.POST['host']
    current_config['DATABASES']['default']['PORT'] = request.POST['port']
    current_config['DATABASES']['default']['USER'] = request.POST['user']
    current_config['DATABASES']['default']['PASSWORD'] = request.POST.get['password']
    content = yaml.dump(current_config)
    nacos_client.set_config(DATA_ID, GROUP, content)

    #重定向到成功页面
    return HttpResponseRedirect('myweb1/config/success/')

def config_seccess(request):
    #获取更新后的配置
    nacos_client = NacosClient(server_addresses=NACOS_SERVERS, namespace=NAMESPACE)
    updated_config = yaml.safe_load(nacos_client.get_config(DATA_ID, GROUP))

    ### 将yaml配置转换为字符串并返回

    #设置更新后的配置URL
    updated_config_url = '/config/success/'

    #返回包含更新后的配置的html页面,yaml配置显示在当前页面,不下载
    context = {'config': yaml.dump(updated_config)}
    return render(request, 'config_success.html', context)

    #会下载修改后的yaml文件
    # content = yaml.dump(updated_config)
    # response = HttpResponse(content, content_type='text/plain')
    # response['Content-Disposition'] = 'attachment; filename="config.yaml"'
    # return response

5. 配置路由urls.py

表单提交时,它将向您在 Django 中定义的 URL 发送 POST 请求。您需要在您的 urls.py 文件中定义一个 URL,以便 Django 可以将请求路由到正确的视图函数.

将 /config/ URL 映射到 config_form 视图函数。当用户提交表单时,Django 将向 /config/ URL 发送 POST 请求,并将请求路由到 config_form 视图函数。

将 /config/success/ URL 映射到 config_success 视图函数。当用户成功提交表单并配置已保存到 Nacos 中时,Django 将重定向到 /config/success/ URL,并将请求路由到 config_success 视图函数。

urlpatterns = [
    path('delete/', views.delete_redis_key, name='delete_redis_key'),
    # path('contact/', views.contact, name='contact'),
    # path('get_config/', views.get_config, name='get_config'),
    path('set_config/', views.set_config, name='set_config'),
    path('config/', views.config_form, name='config_form'),
    path('config/success/', views.config_seccess, name='config_seccess'),
]

6 运行

Python manage.py makemigrations
python manage.py migrate 
python manage.py  runserver 0.0.0.0:8080 

7 访问

默认nacos.yaml的配置

 

 

 

查看验证

 

 

 

 8 报错“'method' object is not subscriptable”

 

 报错“ current_config['DATABASES']['default']['PASSWORD'] = request.POST.get['password']

TypeError: 'method' object is not subscriptable”

 解决方案

# 在set_config函数中,您尝试将请求中的password值赋值给current_config['DATABASES']['default']['PASSWORD']。但是,您使用了request.POST.get['password']而不是request.POST.get('password')。这是因为get方法是一个函数而不是一个可索引的对象。因此,您应该使用圆括号而不是方括号来调用它。请尝试将代码中的request.POST.get['password']更改为request.POST.get('password')。

# current_config['DATABASES']['default']['PASSWORD'] = request.POST.get['password']  修改为:
current_config['DATABASES']['default']['PASSWORD'] = request.POST.get('password')

 

 

 

 

posted @ 2023-07-29 17:51  九尾cat  阅读(510)  评论(0编辑  收藏  举报