def get_options(self): options = None try: if not self.form_field: self.form_field = fields_for_model(self.model, fields=[self.name ])[self.name] if hasattr(self.form_field, 'choices'): #head['options'] = [{'value':x[0],'label':x[1]} for x in self.field.choices] catch = get_request_cache() options_name = '%(model)s.%(field)s.options' % { 'model': model_to_name(self.model), 'field': self.name } if not catch.get(options_name): def myoption(): options = [{ 'value': val, 'label': str(lab) } for val, lab in self.form_field.choices if val != ''] #if self.form_field.required: #options=[{'value':val,'label':str(lab)} for val,lab in self.form_field.choices if val !=''] #else: #options=[{'value':None if val=='' else val,'label':str(lab)} for val,lab in self.form_field.choices ] catch[options_name] = options return options options = myoption #catch.get(options_name) else: options = catch.get(options_name) except exceptions.FieldError: pass return options
def __init__(self, page=1, row_sort=[], row_filter={}, row_search='', crt_user=None, perpage=None, **kw): """ kw['search_args']只是一个记录,在获取到rows时,一并返回前端页面,便于显示。 而真正的查询参数已经被路由到各个查询组件中,具体参见 cls.parse_request / gen_from_search_args 函数 如果需要设置查询的默认参数,需要到 cls.clean_search_args中去设置 """ self.search_args = kw.get('search_args', {}) self.kw = kw self.crt_user = crt_user or get_request_cache()['request'].user #allowed_names = [] #self.row_sort=self.sort(row_sort,crt_user,allowed_names,kw) #self.row_filter=self.filters(row_filter, crt_user, allowed_names,kw) #self.row_search = self.search( row_search,crt_user,allowed_names,kw) self.page = int(page or 1) self.perpage = int(perpage or 20) self.footer = {} self.custom_permit()
def __init__(self, instance=None, name=None, model=None, field=None): self.instance = instance self.name = name self.model = model if not self.model and self.instance: self.model = self.instance.__class__ self.form_field = None self.field = field if not self.field and self.model and name: self.field = self.model._meta.get_field(name) self.request = get_request_cache().get('request') self.crt_user = self.request.user
def gen_from_search_args(cls, search_args, user=None, **kws): args = cls.clean_search_args(search_args) kw = dict(args) kw['search_args'] = args page = kw.pop('_page', '1') perpage = kw.pop('_perpage', None) row_sort = kw.pop('_sort', '').split(',') row_sort = list(filter(lambda x: x != '', row_sort)) q = kw.pop('_q', None) #row_filter={} #for k in cls.filters.names: #arg = kw.pop(k,'') #row_filter[k]=arg user = user or get_request_cache()['request'].user kw.update(kws) #return cls(page,row_sort,row_filter,q,user,perpage=perpage,**kw) return cls(page, row_sort, kw, q, user, perpage=perpage, **kw)
def __init__(self, dc={}, pk=None, crt_user=None, nolimit=False, *args, **kw): dc = self.clean_dict(dc) self.kw = dc.copy() self.kw.update(kw) if pk is not None: self.kw['pk'] = pk if not crt_user: self.crt_user = get_request_cache()['request'].user else: self.crt_user = crt_user self._errors = {} # 太复杂,暂时不要权限 self.nolimit = True
def __init__(self, page=1, row_sort=[], row_filter={}, row_search='', crt_user=None, perpage=None, **kw): """ kw['search_args']只是一个记录,在获取到rows时,一并返回前端页面,便于显示。 而真正的查询参数已经被路由到各个查询组件中,具体参见 cls.parse_request / gen_from_search_args 函数 如果需要设置查询的默认参数,需要到 cls.clean_search_args中去设置 """ self.search_args = kw.get('search_args', {}) self.nolimit = kw.get('nolimit', self.__class__.nolimit) self.kw = kw self.crt_user = crt_user if not self.crt_user: self.crt_user = get_request_cache()['request'].user self.page = kw.get('_page', page) self.custom_permit() allowed_names = self.permited_fields() self.row_sort = self.sort(row_sort, self.crt_user, allowed_names, kw) self.row_filter = self.filters(row_filter, self.crt_user, allowed_names, kw) self.row_search = self.search(row_search, self.crt_user, allowed_names, kw) if not self.row_filter.model: self.row_filter.model = self.model if not self.row_search.model: self.row_search.model = self.model myperpage = self.kw.get('_perpage', perpage) self.pagenum = self.pagenator(pageNumber=self.page, perpage=myperpage) self.pagenum.ps = self self.footer = {} self.is_export_excel = False self.count_query = None
def emit(self, record): global dc if not dc.get('BackendOperation'): from .models import BackendOperation dc['BackendOperation'] = BackendOperation BackendOperation = dc['BackendOperation'] msg = record.getMessage() if record.levelname == 'ERROR': msg += '\n' + record.exc_text user = get_request_cache().get('request').user user_label = user.username if user.is_authenticated else '【匿名用户】' try: db_op_dict = json.loads(msg) content = db_op_dict.pop('content', None) pk = db_op_dict.get('pk', '') if not content: content = parser_form_log(db_op_dict) type_key = db_op_dict.pop('model', '') op = db_op_dict.pop('kind', '') BackendOperation.objects.create( createuser=user_label, inst_pk=pk, op=op, model=type_key, content=content, ) except json.decoder.JSONDecodeError: type_key = '_direct_message' #memo = '' content = msg BackendOperation.objects.create( createuser=user_label, model=type_key, content=content, )
def filter_get_head(self, name, model): this_field= model._meta.get_field(name) catch = get_request_cache() option_name = model_to_name(model)+'.%s.options'%name if not catch.get(option_name): def mychoice_func(): ls=this_field.get_choices() ls=ls[1:] options = [{'value':x[0],'label':x[1]} for x in ls] #options=sorted(options,key=lambda item: ''.join(lazy_pinyin(item.get('label'))) ) catch[option_name] = options return options options= mychoice_func else: options = catch.get(option_name) return { 'name':name, 'label':_(this_field.verbose_name), 'editor': 'com-filter-select', 'options':options }
def view(self, request, name): self.request = request self.engin_url = reverse(self.url_name, args=('aa', ))[:-3] page_cls = self.get_page_cls(name) # 如果需要从定向director页面 if hasattr(page_cls, 'directorPage'): page_cls = page_cls.directorPage(request, name) or page_cls #if not page_cls: #raise Http404() if hasattr(page_cls, 'need_login'): need_login = page_cls.need_login else: need_login = self.need_login if need_login and not self.login_authorized(request): return redirect(self.login_url + '?next=' + request.get_full_path()) # 用在403页面内 request.engin = { 'login_url': self.login_url + '?next=' + request.get_full_path() } if not request.user.is_staff: if hasattr(page_cls, 'need_staff'): if getattr(page_cls, 'need_staff'): raise PermissionDenied('只有职员才能登陆后台界面!') elif self.need_staff: raise PermissionDenied('只有职员才能登陆后台界面!') try: page = page_cls(request, engin=self) if hasattr(page, 'check_permit'): check_rt = page.check_permit() # 可以在这里检测权限,然后跳转 if isinstance(check_rt, HttpResponse): return check_rt ctx = page.get_context() except UserWarning as e: if request.is_ajax(): return JsonResponse({'success': False, 'msg': str(e)}) else: return HttpResponse(str(e)) # 如果返回的事 HttpResponse,表示已经处理完毕了,不需要附加其他属性。 if isinstance(ctx, HttpResponse): return ctx # 如果是ajax请求,则只返回业务数据 if request.is_ajax() and not request.GET.get( '_ajax_html'): #and not getattr(page,'ajax_html',False): resp = HttpResponse(json.dumps(ctx), content_type="application/json") if request.GET.get('_accept') == 'json' or 'json' in request.META.get( 'HTTP_ACCEPT', ''): resp = HttpResponse(json.dumps(ctx, ensure_ascii=False), content_type="application/json") else: named_ctx = get_request_cache()['named_ctx'] if ctx.get('named_ctx'): named_ctx.update(ctx.get('named_ctx')) ctx['named_ctx'] = evalue_container(named_ctx) ctx['engine_name'] = self.url_name ctx['brand'] = self.brand ctx['title'] = self.title ctx['menu_search'] = self.menu_search ctx['menu'] = self.get_menu(request) ctx['page_name'] = name ctx['engin_url'] = self.engin_url if isinstance(self.root_page, (str, str)): ctx['root_page'] = self.root_page else: ctx['root_page'] = self.root_page(self.url_name) if hasattr(page, 'get_template'): template = page.get_template() else: template = page.template #ctx=self.get_ctx(ctx) ctx['template'] = template ctx['ui_theme'] = self.ui_theme if hasattr(page, 'get_label'): ctx['page_label'] = page.get_label() ctx['head_bar_data'] = self.get_head_bar_data(request) ctx['js_config'] = self.getJsConfig() if hasattr(page, 'getExtraJs'): ctx['extra_js'] = page.getExtraJs(ctx) ctx = self.custome_ctx(ctx) resp = render(request, template, context=ctx) if getattr(page, 'get_cache_control', None): kw = page.get_cache_control() patch_cache_control(resp, **kw) if getattr(page, 'processRespons', None): page.processRespons(resp) return resp
def __init__(self, dc={}, pk=None, crt_user=None, select_for_update=True, *args, **kw): """ 调用情况: 1. ajax save 时 2. ajax get 时,获取数据,或者获取一个新的row数据。 @dc: 当post save时 ,dc是前端传来的row字典。可以看到dc被传入了super函数,既传入了django.form中当做row参数。 如果要设置instance的默认值,可以在kw中传入,这样第一次返回前端的时候就有值。 如果在dc中传入默认值,第一次返回前端时,没有值,因为初始化时,不会调用 save_form 函数。 当get 时,dc是前端传来的url参数中的dc字段,(基本上没有用) * 后端设置默认值: 1. 在clean_dict 中设置 ; 2. 在clean_save中设置时,但是经历了 clean函数,可能验证不能通过 * 前端设置默认值: 在 table的 add_new 操作中 添加 pre_set 。注意 foreignkey 需要加 _id """ if not crt_user: #self.crt_user=dc.get('crt_user') self.crt_user = get_request_cache()['request'].user else: self.crt_user = crt_user self.kw = kw.copy() # 修正参数 # 2021/5/24 挪到这里 dc = self._clean_dict(dc) dc = self.clean_dict(dc) if dc.get('instance'): self.kw['instance'] = dc.pop('instance') if pk is not None: pass elif dc.get('pk') != None and dc.get('pk') != '': pk = dc.get('pk') elif dc.get('id') != None and dc.get('id') != '': pk = dc.get('id') else: if self.kw.get('instance'): pk = self.kw['instance'].pk else: pk = None if not pk: self.is_create = True else: self.is_create = False form_kw = {} if 'instance' not in self.kw: if pk == '-1': # -1 表示 最后一个记录 (一般用不到) form_kw['instance'] = self._meta.model.objects.last() elif pk != None: # 很多时候,pk=0 是已经创建了 try: if select_for_update: form_kw[ 'instance'] = self._meta.model.objects.select_for_update( ).get(pk=pk) else: form_kw['instance'] = self._meta.model.objects.get( pk=pk) except self._meta.model.DoesNotExist: raise UserWarning('Id=%s that you request is not exist' % pk) # 感觉 instance不存在时,报错404可能不太合适,所以还是用普通报错 #raise Http404('Id=%s that you request is not exist'%pk) else: # 前端初始化字段值,在 add_new opertions里面添加 pre_set:'rt={}' field_names = [] for field in self._meta.model._meta.get_fields(): if isinstance(field, models.ForeignKey): field_names.append('%s_id' % field.name) else: field_names.append(field.name) init_dc = { k: v for k, v in self.kw.items() if k in field_names } form_kw['instance'] = self._meta.model(**init_dc) #(**self.kw) else: form_kw['instance'] = self.kw.pop('instance') self.custom_permit() # 强制 readonly的字段,不能修改 inst = form_kw['instance'] # 如果row有meta_change_fields 字段,那么该次请求,只能修改这些字段,其他字段一律还原 meta_change_fields = [] if dc.get('meta_change_fields'): meta_change_fields = dc.get('meta_change_fields').split(',') # 强制保存字段,不验证是否改变,并且其他字段都不能改变 #if dc.get('meta_change_fields'): #force_change_fields = dc.get('meta_change_fields').split(',') #force_change_fields += self.overlap_fields #for k in self.permit.changeable_fields(): #if k not in force_change_fields: #fieldcls = inst.__class__._meta.get_field(k) #if isinstance(fieldcls, models.ForeignKey): #dc[k] = getattr(inst, "%s_id" % k) #continue #dc[k] = getattr(form_kw['instance'] , k) # todict -> ui -> todict(compare) -> adapte_dict readonly_waring = [] simdc = sim_dict(inst) orgin_simdc = dict( simdc) # 将可json化的结果保存下来,后面记录日志会用到。simdc被clean处理过,可能不能json化了 #n1 由于 multichoice.fullchoice, -1代表全部,出库的时候,转换为[1,2,3], 而数据库中是-1,造成数据库 出入不一致,所以加入以下_clean代码,将simdc再次还原为数据库数据。(simdc是走了to_dict转换函数的) #n2 TODO:可能会在以后移除这里的_clean_dict,因为应该保持数据库数据的 数据库->前端->后端 的一致性,就算显示需求,也应该利用_label等特殊字段。 simdc = self._clean_dict(simdc) #simdc = self.clean_dict(simdc) if not self.is_create: self.readonly = list(self.readonly) self.readonly += self.const_fields if meta_change_fields or self.readonly: # 修正只读字段 for k in dict(dc): if k in self.readonly or (meta_change_fields and k not in meta_change_fields): if k in self.readonly_change_warning and adapt_type( dc[k]) != adapt_type(simdc.get(k)): readonly_waring.append(k) dc[k] = simdc.get(k) if 'meta_org_dict' in dc: dc['meta_org_dict'].pop(k) #if hasattr(inst, "%s_id" % k): # 如果是ForeignKey,必须要pk值才能通过 form验证 #fieldcls = inst.__class__._meta.get_field(k) #if isinstance(fieldcls, models.ForeignKey): #dc[k] = getattr(inst, "%s_id" % k) #continue #if hasattr(inst,k): #dc[k] = getattr(inst , k) if readonly_waring: # and not dc.get('meta_overlap_fields') == '__all__' : 这个有安全隐患 ,所以去掉 raise OutDateException( '(%s)的%s已经发生了变化,请确认后再进行操作!' % (inst, [field_label(inst.__class__, k) for k in readonly_waring])) # 真正的验证各个参数是否过期,是在clean函数中进行的。 # 参数的修正挪到最上面 #dc = self._clean_dict(dc) #dc=self.clean_dict(dc) self.kw.update(dc) super(ModelFields, self).__init__(dc, *args, **form_kw) # 2021-05-07 挪到上面 #if not self.instance.pk: #self.is_create = True #else: #self.is_create = False #if not self.is_create: ## 有时候 self.changed_data 会错误包含其他字段 ## 有问题,因为有些 foreignkey 或者 onetoone字段 读取的时候不存在,报异常 #for name in list( self.changed_data ): #if getattr(self.instance,name) == dc.get(name): #self.changed_data.remove(name) self.pop_fields() self.init_value() self.op_log = {} # 保留下instance的原始值,用于记录日志; # 因为simdc被clean函数处理过,可能不能json化,所以使用 orgin_simdc。后面 orgin_simdc 用于保存日志 self.before_changed_data = { k: v for k, v in orgin_simdc.items() if k in self.changed_data } # sim_dict(self.instance, include= self.changed_data)
def do_logout(**kw): request = get_request_cache()['request'] auth.logout(request)
def __init__(self, row): self.request = get_request_cache()['request'] self.row = row self.code_key = 'validate_code_user_%(username)s' % self.row self.count_key = 'login_count_user_%(username)s' % self.row self.code_life = timezone.now() - timezone.timedelta(minutes=30)
def clean_field(self, dc, name): "现在无法调用该函数,所以这里还需要考虑下。" if not dc.get(name): request = get_request_cache()['request'] dc[name] = request.user.pk return dc.get(name)