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标签中

}

 

 

 

  

 

posted @ 2018-08-31 22:16  Mr.GLH  阅读(158)  评论(0)    收藏  举报
Top↑