# 4.删除 # 在修改记录页面左下角添加一个删除按钮,一个链接,跳转至一个提示删除内容的页面,确认删除; # 关联删除,删除记录同时也删除外键的关联表; # table_obj_common.html <div class="form-group"> <div class="col-sm-10"> <a href="{% table_obj_delete app_name model_name form_obj.instance.id %}">DELETE</a> </div> </div> # urls.py url(r‘^(\w+)/(\w+)/(\d+)/add/$‘, views.table_obj_delete, name="table_obj_delete"), # views.py @login_required def table_obj_delete(app_name,model_name,obj_id): """删除记录""" admin_class = site.enabled_admins[app_name][model_name] obj = admin_class.model.objects.get(id=obj_id) return render(request, ‘kingadmin/table_obj_delete.html‘,locals()) # table_obj_delete.html delete {{ obj }} <!-- obj代表当前这条记录 --> # 在删除页面确认,后台删除该记录; # >> a = models.CustomerInfo.objects.first() # >> a.delete() # 会不会删除关联的表数据?会;|跟踪记录表; # django-admin在删除时显示友好提示,列出所有关联表; # 一层层递归所有外键,删除; # table_obj_delete.html {% display_all_related_objs obj as all_related_obj_eles%} {{ all_related_obj_eles|safe }} # kingadmin_tag.py @register.simple_tag def display_all_related_objs(obj): """显示要被删除对象的所有关联对象""" ele = "<ul>" ele += "<li>%s</i>"%obj # 1.forignkey | get_internal_type() for reversed_fk_obj in obj._meta.related_objects: related_table_name = reversed_fk_obj.name related_lookup_key = "%s_set"%related_table_name # >> getattr(a,‘customerinfo_set‘) # 获取关联表 # >> getattr(a,‘customerinfo_set‘).all() # 关联表所有对象 related_objs = getattr(obj,related_lookup_key).all() # 反向查所有关联数据 ele += "<li>%s</li><ul>"%related_table_name # 如果是many_to_many就不需要深入递归,打印影响的数据 if reversed_fk_obj.get_internal_type() == "ManyToManyField": for i in related_objs: ele += "<li><a href=‘/kingadmin/%s/%s/%s/change/‘>%s</a> 记录中与%s相关数据将被删除</li>" % (i._meta.app_label,i._meta.model_name,i.id,i, obj) # 课程相关 else: for i in related_objs: ele += "<li>%s</li>" % i ele += display_all_related_objs(i) # 调用自己,递归查找 ele += "<ul></li>" ele += "</ul>" return ele # >> a._meta.fields # 获取所有字段 # >> a._meta.fields_map # 外链的表映射 # (‘student‘:<ManyToOneRel:crm.student>,...) # >> from crm import models # >> a = models.CustomerInfo.objects.all()[1] # >> a # <CustomerInfo: ‘大西瓜‘> # 学员表中的学生是外键关联着客户表的;一对多反向查询(外键设置在student); # >> a.student_set.select_related() # 获取当前查询对象的所有外键字段对应表的查询集:student # <QuerySet [<Student:‘大西瓜‘ >]> # 只要a._meta.fields_map遇到ManyToOneRel的,就反向去查找: # 要考虑自关联,referer_from 转介绍 # >> a._meta.fields_map # (...‘customerinfo‘:<ManyToOneRel:crm.student>...) # 映射中含有当前的表,忽略; # 综合: # //////a._meta.fields可以获得所有foreignkey # 不需要管,学生删除不影响客户表; # a._meta.related_obj 可以获取所有反向关联;而不使用a._meta.fields_map,因为有个脏数据需要判断; # a._meta.many_to_many可以获取多对多关系的数据; # 多层级递归删除 # 课程-班级-上课记录-学习记录; # 课程被删除,与之多对多关系的客户信息不会被删除,但是字段会收到影响; # 给展示记录添加链接跳转查看 ele += "<li><a href=‘/kingadmin/%s/%s/%s/change/‘>%s</a> 记录中与%s相关数据将被删除</li>" % (app_name,model_name,i.id,i, obj) {% display_all_related_objs i._meta.app_label,i._meta.model_name,i.id,i, obj as all_related_obj_eles%} # table_obj_delete.html | 点击删除所有关联数据 <form method=‘post‘> {% csrf_token %} <input type=‘submit‘ class=‘btn btn-danger‘ value=‘确认删除‘> <a>返回</a> </form> # views.py @login_required def table_obj_delete(app_name,model_name,obj_id): """删除记录""" admin_class = site.enabled_admins[app_name][model_name] obj = admin_class.model.objects.get(id=obj_id) if request.method == ‘POST‘: obj.delete() return redirect(‘/kingadmin/{app_name}/{model_name}/‘.format(app_name=app_name,model_name=model_name)) return render(request, ‘kingadmin/table_obj_delete.html‘,locals())