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')