modelform+代码发布系统前奏

注意点

<form class="form-horizontal" method="post" novalidate>
method="post"  : 指定form表单提交方式
novalidate  : 去除前端校验
field_obj.widget.attrs['class'] = 'form-control'  : 添加class='form-control'属性
<span style="color: red">{{ form_obj.hostname.errors.0 }}</span> # 渲染错误信息

# 如何区分编辑还是新增就是看有没有instance参数
form_obj = ServerModeForm(data=request.POST)  # 新增
form_obj = ServerModeForm(instance=edit_obj) # 渲染标签,渲染数据
form_obj = ServerModeForm(data=request.POST,instance=edit_obj)  # 编辑


<a href="{% url 'server_edit' server_obj.pk %}">编辑</a>

form.html 添加编辑页面

{% extends 'base.html' %}

{% block content %}
    <form class="form-horizontal" method="post" novalidate>
        {% csrf_token %}
        {% for foo in form_obj %}
            <div class="form-group">
            <label for="{{ foo.id_for_label }}"
                   class="col-sm-2 control-label">{{ foo.label }}</label>
            <div class="col-sm-10">
                {{ foo}}
                <span style="color: red">{{ foo.errors.0 }}</span>
            </div>
        </div>
        {% endfor %}
        <div class="form-group">
            <div class="col-sm-offset-2 col-sm-10">
                <button type="submit" class="btn btn-success">提交</button>
            </div>
        </div>
    </form>
{% endblock %}

ModelForm

from django.forms import ModelForm
from app01 import models

class ServerModeForm(ModelForm):
    class Meta:
        model = models.Server
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x0000029EBC724518>)])
        # print(self.fields)
        # 给所有的字段加class的属性
        for k, field_obj in self.fields.items():
            field_obj.widget.attrs['class'] = 'form-control'

添加

html

<a href="{% url 'server_add'%}" class="btn btn-danger" style="margin: 10px 0">添加数据</a>
def server_add(request):
    # 1 先生成一个modelform的空对象
    form_obj = ServerModeForm()  # 渲染标签
    if request.method == 'POST':
        form_obj = ServerModeForm(data=request.POST)  # 新增
        # 3 判断是否合法
        if form_obj.is_valid():
            # 保存数据
            form_obj.save()
            # 跳转到服务器的展示页
            # return redirect('/server/list')
            return redirect('server_list')  # 还可以写别名  但是如果出现有名无名分组的反响解析 则必须使用reverse方法
    # 2 将该对象传给html
    return render(request, 'form.html', locals())

编辑

html

{% for server_obj in server_queryset %}
<tr>
	<td>{{ server_obj.pk }}</td>
	<td>{{ server_obj.hostname }}</td>
	<td>
		<a href="{% url 'server_edit' server_obj.pk %}">编辑</a>
		<a href="" onclick="removeDate(this,{{ server_obj.pk }})" >删除</a>
	</td>
</tr>
{% endfor %}

py

def server_edit(request, edit_id):
    edit_obj = models.Server.objects.filter(pk=edit_id).first()
    # 生成待编辑的modeform对象
    form_obj = ServerModeForm(instance=edit_obj)  # 渲染标签,渲染数据

    if request.method == 'POST':
        form_obj = ServerModeForm(data=request.POST, instance=edit_obj)  # 编辑
        if form_obj.is_valid():
            form_obj.save()
            return redirect('server_list')
    return render(request, 'form.html', locals())

删除

html

{% for server_obj in server_queryset %}
<tr>
	<td>{{ server_obj.pk }}</td>
	<td>{{ server_obj.hostname }}</td>
	<td>
		<a href="{% url 'server_edit' server_obj.pk %}">编辑</a>
		<a href="" onclick="removeDate(this,{{ server_obj.pk }})" >删除</a>
	</td>
</tr>
{% endfor %}

# 删除Js
function removeDate(ths,sid) {
        var res = confirm('确定删除吗?');
        if (res){
            $.ajax({
                url:'/server/delete/'+sid+'/',
                type:'get',
                success:function (args) {
                    if (args.status){
                        $(ths).parent.parent.remove()   # DOM操作,删除标签
                    }
                }
            })
        }
    }

py

def server_delete(request, delete_id):
    models.Server.objects.filter(pk=delete_id).delete()
    return JsonResponse({'status': True})  # 返回给前端,表示已经删除

代码优化

优化1

将所有的modelform单独抽取出来

将modelform类中所有公共的部分抽取出来形成基类

# 父类
from django.forms import ModelForm


class BaseModelForm(ModelForm):
    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # print(self.fields)  # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
        # 给所有的字段加class属性
        for k,field_obj in self.fields.items():
            field_obj.widget.attrs['class'] = 'form-control'
            
            
            
# 子类
from app01.myforms.base import BaseModelForm
from app01 import models


class ServerModelForm(BaseModelForm):
    class Meta:
        model = models.Server
        fields = "__all__"

优化2

当模型表字段特别多的时候,并且并不是所有的字段都需要展示到前端给用户观看

from django.forms import ModelForm


class BaseModelForm(ModelForm):
    # 自定义字段是否需要加额外属性的配置
    exclude_bootstrap = []

    def __init__(self,*args,**kwargs):
        super().__init__(*args,**kwargs)
        # print(self.fields)  # OrderedDict([('hostname', <django.forms.fields.CharField object at 0x10c99c198>)])
        # 给所有的字段加class属性
        for k,field_obj in self.fields.items():
            if k in self.exclude_bootstrap:
                continue  # 排除在外不添加样式
            field_obj.widget.attrs['class'] = 'form-control'

优化3

项目表需要额外添加字段

    # 线上服务器地址
    path = models.CharField(verbose_name='线上地址',max_length=64)
    # 关联服务器
    """
    一个项目可以跑在多个服务器上
    一个服务器其实也可以跑多个项目 (公司服务器不够的时候 可以混用)
    """
    servers = models.ManyToManyField(to='Server',verbose_name='关联服务器')
    
    
    
# 项目展示页面额外展示当前两个字段


<th>线上地址</th>
<th>线上关联服务器</th>

<td>{{ project_obj.path }}</td>
<td>
	{% for server_obj in project_obj.server.all %}
		<span style="border: 1px solid black;padding: 5px">{{ server_obj.hostname }}</span>
	{% endfor %}
</td>
posted @ 2020-04-15 22:32  Jeff的技术栈  阅读(169)  评论(0编辑  收藏  举报
回顶部