CRM新知识
CRM组建中的新语法总结:
1,通过模型表对象(类,下面的model)获取模型表名和对应的app名
model_name = model._meta.model_name # 拿到模型表名 app_name = model._meta.app_label # 拿到app名称
2, 通过字段(字符串形式)获取到模型表中对应格那个字段对象,然后可以拿模型表中定义是的参数,相当于实例属性
field_obj = self.config_obj.model._meta.get_field(field)
val = field_obj.verbose_name
3,分页保留url上的参数
# 再每页展示数据的时候,保留url的参数, params = self.request.GET # 获取原来的QueryDict,但是 是不可变的,但是他的源码里表示深copy一份是可以变得, # 所以我们深copy一份 params = copy.deepcopy(params) # 现在这个字典就有了我们请求时所有的参数了 # print(params) # <QueryDict: {'page': ['2'], 'x': ['2']}> # 然后利用他的urlencode()方法获取类似url格式的参数 # url_params = params.urlencode() # page=2&x=2 # 使用: params["page"] = 1 # 只要把自己需要修改的参数,修改就可以,其他参数就可以保留 first_page_tag = '<li><a href="?{}">首页</a></li>'.format(params.urlencode())
4,在py文件中,返回一段html代码,然后在前端渲染,使用mark_safe()
from django.utils.safestring import mark_safe
return mark_safe("<button class='btn btn-danger del_btn' del_id='{}' type='button'>" "<i class='fa fa-trash fa-fw' aria-hidden='true'></i>删除</button>".format(obj.pk))
5, search中的Q查询新用法
from django.db.models import Q
# search功能 # 重要的语法 # 该语法的特点是 Q()对象的children中append条件,条件为一个元组,(字段字符串形式,条件) condition = request.GET.get("condition", "") # 实例化一个Q对象 search_obj = Q() # 多个append(),之间为 “或” 的关系,默认为“且”的关系,加上 search_obj.connector = "or"变为“或” search_obj.connector = "or" if condition: for search_field in self.search_fields: # 循环每一个字段,把字段名,和对应的条件加进去 search_obj.children.append((search_field + "__icontains", condition)) # 做字符串拼接,做模糊查询,如 "title"+"__icontains" 得到---> "title__icontains" # 如果取不到condition, 那么就传一个空的Q对象,则为查询所有数据
6,actions中要注意:
对于多个checkbox标签,我们为其加了name="xxx"后,在提交中,form表单会把我们选中的所有checkbox的value值放在那个name="xxx"中的列表中,我们可以通过getlist取到所有的数据,
<input type='checkbox' value='{}' name='pk_list'> # 把所有的value放在name="pk_list"中组成一个列表
pk_list = request.POST.getlist("pk_list") # 获取到所有的选中的checkbox标签提交过来的数据id
注意:select标签多选时,也是拿到多个值
7 ,页面展示时,分为表头和表内容,表头中,如果是个函数,那么循环时,让其传入不同的参数,获取到不同的结果,然后分别渲染到表头和表内容:
# 自定义函数列 def edit(self, obj=None, is_header=False): if is_header: return "编辑" return mark_safe("<a href='{}' class='btn btn-warning'>" "<i class='fa fa-pencil-square-o fa-fw' aria-hidden='true'></i>编辑</a>" .format(self.get_change_url(obj)))
# 在表头这么传参数
if callable(field): # 如果是函数,就执行,而且是表头,传参is_header=True val = field(self.config_obj, is_header=True)
# 在表内容中这么传参数 if callable(field): val = field(self.config_obj, obj)
8,ForeignKey的参数:
def __init__(self, to, on_delete=None, related_name=None, related_query_name=None, limit_choices_to=None, parent_link=False, to_field=None, db_constraint=True, **kwargs):
on_delete : 两张关联表的关联字段的同步删除;
related_name=None,related_query_name=None: 这两个字段都是在ORM中反向查询时为关联表其别名使用的;
limit_choices_to:在使用modelform时,对于关联字段会展示 select标签,里面option标签都是关联字段下面的所有对象,使用 limit_choices_to 字段之后,可以进行过滤操作:
teachers = models.ManyToManyField(verbose_name='任课老师', to='UserInfo', limit_choices_to={"depart_id__in":[1000,1001]} ) tutor = models.ForeignKey(verbose_name='班主任', to='UserInfo', related_name="class_list", limit_choices_to={"depart_id":1003} )
parent_link=False: 这个字段暂时不明;
to_field=None:使用该字段,存在外键的表中的那个外键字段就不是 主键__id 了,二十 to_field指定的字段__id
db_constraint=True: 将该值变为False,那么就算两张表没有关联字段,我们自己写的关联字段也可以使用ORM中提供的各种查询方法(包括正向,反向)
9,通过字段获取表
from rbac import models field_obj = models.Role._meta.get_field("permissions") # 通过字段获取字段对象 field_obj.rel.to # 通过该方法 获取该字段对应的那个有关联属性的 那个模型表类 <class 'rbac.models.Permission'> field_obj.rel.to.objects.all() <QuerySet [<Permission: 查看订单>, <Permission: 添加订单>, <Permission: 修改订单>, <Permission: 删除订单>, <Permission: 查看校区>,.......
10,ORM操作中,对于外键字段的查询,筛选: 3中方式都一样
models.Book.objects.filter(publish=publish_obj) models.Book.objects.filter(publish_id=1) models.Book.objects.filter(publish=1)
11,pop功能,+的渲染:
def get_new_form(self, form_obj): # from django.forms.boundfield import BoundField 这个类中的初始化方法中 有 self.field self.name for form in form_obj: # 打印form是该类的str方法,显示为标签形式 # print(type(form)) # 全是这个类 <class 'django.forms.boundfield.BoundField'> # print(form.field) .field方法 显示原型 # 对应的类 # <django.forms.fields.CharField object at 0x00000229B7DB75C0> # <django.forms.fields.DateField object at 0x00000229B7DB7630> # <django.forms.fields.DecimalField object at 0x00000229B7DB76A0> # <django.forms.models.ModelChoiceField object at 0x00000229B7DB7710> # 这个ModelChoiceField类是 OneToOneField 和 ModelMultipleChoiceField 的父类 # <django.forms.models.ModelMultipleChoiceField object at 0x00000229B7DB7780> from django.forms.models import ModelChoiceField if isinstance(form.field, ModelChoiceField): # 如果是多对多字段, form.is_pop = True # 就给form添加一个自定义的属性is_pop,模板根据该属性决定是否渲染那个 加号 # 这里需要注意,我们点加号是要添加 出版社或者作者,所以,那个url需要拼接; # 并且,我们在添加完之后需要把那个数据,返回到我们添加书籍的页面上; # 所以我们需要做一些自定义属性; # print(form.name) # title publishDate price publish authors 所有字段的字符串名 # 根据字段字符串名称获取字段对象,在获取对应的模型表 field_obj = self.model._meta.get_field(form.name) # 根据字段字符串名称获取字段对象 rel_model = field_obj.rel.to # 根据字段对象获取对应的模型表 类 rel_model_name = rel_model._meta.model_name rel_app_name = rel_model._meta.app_label # 反向解析,获取要添加的url _url = reverse("{}_{}_add".format(rel_app_name, rel_model_name)) # 把这个url做成form的自定义属性 form.url = _url # 在做一个用于返回数据,做dom操作时,具体给那个dom,添加,的自定义属性 form.pop_back_id = "id_" + form.name # 因为form组件生成的标签 id值都是 id_"字段名",所以我们这么拼接 return form_obj
12 pop功能中 如何打开新页面:
给+好绑定 点击事件onclick=pop()
var pop_back_id; // 定义一个全局的变量,记录要给那个标签 进行dom渲染操作 function pop(url, back_id) { pop_back_id = back_id; // 把那个拼接的id值,赋给全局变量pop_back_id,做DOM操作使用 window.open(url+"?pop=1", url+"?pop=1", "width=800, height=500, top=100, left=100") // 给url + "?pop=1",是加一个参数,与正常添加 作区分,,如果能取到pop参数,说明是pop窗口的添加, // 我们需要返回的就不是查看页面了,而是返回原来的页面,做dom操作 }
13 pop功能中,如何实现父子窗口之间 交流,:
子窗口可以调用父窗口的函数,并且传递参数
// 子窗口和父窗口通信,子窗口可以调用父窗口的函数 window.opener.pop_back_func("{{ text }}", "{{ pk }}"); window.close()
14 pop功能中,父窗口最后的 dom操作,即option标签的渲染
// pop窗口的操作完成之后,利用子窗口关闭之前,调用这个方法,进行父窗口的渲染 function pop_back_func(text, pk) { console.log(text, pk); console.log("--->", pop_back_id); var $option = $("<option>"); // jquery 创建一个<option></option>标签 $option.text(text); $option.attr("value", pk); $option.attr("selected", "selected"); // 注意 这里两个都是字符串形式 $("#"+pop_back_id).append($option); // 把这个标签添加到我们的那个标记好的 select标签中 }

浙公网安备 33010602011771号