或css
或html
大致相同,但小程序直接this.data的属性是不能够同步到视图的,必须调用this.setData()方法! 1.双向绑定:vue默认支持双向绑定,微信小程序须要借助data。 2.取值:vue中,经过this.reason取值。小程序中,经过this.data.reason取值。 3.定义方法:小程序使用 在app.js中定义便可,vue的方法经过写在method中进行定义。 1. 去变量的时候: - 小程序 wx:for = "lists" - Vue是 v-for = "item in lists" 2. 调用data模型(赋值)的时候: - 小程序:this.data.item //调用 this.setData({item:1}) //赋值 - vue: this.item //调用 this.item =1 //赋值 小程序的双向绑定实际上并非双向绑定 若是在小程序.js文件中改变了某个变量的值 那么页面上的值并不会跟着改变 若是想要页面上的值也跟着改变的话 须要经过setData来操做 而Vue默认就是双向绑定 只改变了某个变量的值 页面上也会跟着改变
或前端
优点:vue
劣势:python
小程序支持 ES6 语法 在返回成功的回调里面处理逻辑 Promise 异步 async/await 在回调函数中调用下一个组件的函数: **app.js** success:function(info){ that.apirtnCallback(info) } **index.js** onLoad:function(){ app.apirtnCallback = res =>{ console.log(res) } }
使用wx.getUserInfo方法 withCredentials为true时,可获取encryptedData,里面有union_id.后端须要进行对称解密。web
注:插件渲染会致使页面加载变慢,建议在后台对文章内容的html进行过滤,后台直接处理批量替换p标签div标签为view标签。而后其余的标签让插件来作。ajax
用view代替scroll-view,设置onPullDownRefresh函数实现redis
wx.miniProgram.navigateTo({ url:’pages/login/login’+’$params’ }) **//跳转到小程序导航页面** wx.miniProgram.switchTab({ url:’/pages/index/index’ })
wx.navigateTo() wx.redirectTo() wx.switchTab() wx.navigateBack() wx.reLaunch()
wx.navigateTo():保留当前页面,跳转到应用内的某个页面。可是不能跳到 tabbar 页面 wx.redirectTo():关闭当前页面,跳转到应用内的某个页面。可是不容许跳转到 tabbar 页面 wx.switchTab():跳转到 tabBar 页面,并关闭其余全部非 tabBar 页面 wx.navigateBack()关闭当前页面,返回上一页面或多级页面。可经过 getCurrentPages() 获取当前的页面栈,决定须要返回几层 wx.reLaunch():关闭全部页面,打开到应用内的某个页面
能够经过this.setData来进行改变数据库
能够经过wx.setStorageSync('键名', 对应的值)来进行数据持久化django
微信小程序属于轻量级的app 可是限制在微信中,开发周期短,功能较少,占用空间少,
app就相反 须要占用额外内存 开发周期长
【【我理解的意思至关于flask和django的区别】】
在开发的过程当中我没有太多的问题可是个人同事遇到了一个问题,怎么在序列化器中获取request的值。经过源码的研究发现self.context["reqeust"].xx 能够获取到值 大大提升了数据的粘性和开发效率 在小程序端 使用模块的引用设置url值 方便url路径的更改
会写drf源码 在小程序的项目中我经过自定义方法 重构drf内部方法 实现更高的扩展性。
开始:小程序、api(主)
他分为两大模块,有用户动态模块,拍卖模块,用户动态模块又分为发布功能,动态展现功能以及常见的用户交互功能,拍卖模块又分为专场-拍品,由后台管理人员维护更新,连我总共有3我的开发,总共开发了三个月,我离职时,项目还在开发,正在开发xx
首先,在作这个功能的时候,会先在纸上画出来其中的逻辑,而后再把后端须要的值传过去。作这个后端api时,须要拿到前端的数据,判断它是否使用优惠券了,是否使用保证金了,是否有地址了,选择什么方式支付了,余额仍是微信支付,还有该用户的支付价格,传到后端以后进行数据校验,首先判断地址是否存在,而后判断订单是否合法,是否使用了优惠券,是否使用保证金,用户的支付价格和后端计算的价格是否相符,因为支付环节必须保证一次完成,因此给它加了事务,订单表的查询加了锁,经过一系列校验,而后进行支付。支付成功以后,订单表记录,保证金抵扣记录,优惠券使用记录,退保证金记录,都须要进行相应的修改
建立一个compent文件夹,里面建立一个tabbar页面,取消原有的tabbar页面。须要在app.json中输入compent:ture,在自定义的pages页面中写入<tabbar selected="{{0}}"></tabbar>进行选中效果显示
var pages = getCurrentPages() var prevPage = pages[pages.length-2]; # prevPage是上一个页面的对象,下面能够设置页面的值 prevPage.setData({ topicText: topicInfo.title }); 也能够执行那个页面的函数,prevPage.getInfo(orderId); tabbar页面没问题"
celery暂时只用在日志这方面,其余方面没有考虑过 拍卖业务关于订单的处理 & 状态的变化 celery和crontab的区别?
redis://:admin@192.168.88.88:8888,在ip地址前面加上:admin@ - 传参 Connect(host='..',port....) - 字符串 connect_by_url('redis://密码@192.168.88.88:8888/,')
var dataList = ['alex','lld','uuid'] for(var i in dataList){ (function(data){ wx.request({ url:'xxx', success:(res) => { console.log(data); } }) })(dataList[i]) } 由于微信小程序处理函数是异步执行的,异步执行形成的结果可能和预期的不合,若是函数中有循环,最后的结果都同样,因此使用js闭包能够解决这个问题。 ###
算是坑过吧,我在作发布功能时,须要将用户选中的图片和其余信息发送上去,图片发送到桶中,其余信息须要放到数据库中,而其余信息须要包含图片的路径地址,这个路径地址须要上传到桶中返回,而异步执行会形成图片上传和其余信息发送时间不一致,形成的结果是图片路径不能保存到数据库中。
开发文档 https://developers.weixin.qq.com/miniprogram/dev/framework/open-ability/login.html
a.使用wx.login获取code值 b.使用wx.request请求后台的api,把code值做为参数发送给后台 后台会根据咱们传过去的code值来获取openid和session_key 微信官方建议:为了安全不要直接采用openid和session_key来做为用户身份的标识 把微信帐号登陆态生成一个session id并维护在咱们本身的session机制中,而后把这session id派发到小程序客户端做为session标识来使用。返回一个自定义token值 c.把session_id保存到本地,使用wx.setStorage把token保存到本地, d.在你须要使用的地方session_id的地方调用wx.getStorage(建议你也能够封装一个方法,就能够很方便的取出你要的数据) e.定义登录方法 1.使用官方提供的button返回值 <button class=""submit"" open-type=""getUserInfo"" bindgetuserinfo=""onClickSubmit""> 登陆 | 注册</button> 2. 导入全局app var app=getApp(); 3.传值 app.initUserInfo(res.data.data, e.detail.userInfo) 4.封装app.js #封装全局数据 globalData: { userInfo: null, // {phone:xxx,token:xxxx} authorInfo: null, }, initUserInfo: function (res, localInfo) { console.log(""app打印"",localInfo) var info = { id:res.id, token: res.token, phone: res.phone, nickName: localInfo.nickName, avatarUrl: localInfo.avatarUrl } // 1.去公共的app.js中调用globalData,在里面赋值。(在全局变量赋值) this.globalData.userInfo = info;//{phone:xxx,token:xxxx} // 2.在本地“cookie”中赋值 wx.setStorageSync(""userInfo"", info); 5.取数据 var app=getApp(); app.globalData.userInfo ##认证 f.在你调用那些须要后台登陆才能够访问的接口的时候,就能够把session_id做为参数加到header或者query里面就能够了 wx.checkSession 为何要用wx.checkSession() 有时候,咱们会由于session_key不正确而致使解密或者校验签名失败。有几方面的缘由: 一、由于wx.login()被调用时,用户的session_key会被更新致使就session_key失效。因此,在调用wx.login()的时候应该要明确须要登陆以后再调用。 二、另外,微信不会把session_key的有效期告诉咱们,用户越频繁使用微信,session_key的有效期就更长。 由于,就须要调用wx.checkSession()来校验当前用户的session_key是否有效。 *使用wx.checkSession来检测登陆状态是否过时,若是过时了才调用登陆接口,而不是每次进入小程序都调用登陆接口,这样也能够优化页面加载速度 onLoad: function () { wx.checkSession({ success: function(res){ console.log(""处于登陆态""); }, fail: function(res){ console.log(""须要从新登陆""); wx.login({}) } }) } "
1.认证的错误定义的错误码不能返回自定义 被403捕获 from rest_framework import exceptions class UserAuthentication(BaseAuthentication): """""" 用户认证,用户必须先登陆。 """""" def authenticate(self, request): token = request.META.get('HTTP_AUTHORIZATION', None) print(token) if not token: print('走token') raise exceptions.AuthenticationFailed() print('xxxx') user_object = api.UserInfo.objects.filter(token=token).first() print(""xxxx"", user_object) if not user_object: print(""走这了"") raise exceptions.AuthenticationFailed() print(""打印返回值"", user_object, token) return (user_object, token) 2.认证的简化源码流程 def dispatch(self, request, *args, **kwargs): try: self.initial(request, *args, **kwargs) if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) #因此的异常被这样优先捕获 3.handle def handle_exception(self, exc): """""" Handle any exception that occurs, by returning an appropriate response, or re-raising the error. """""" if isinstance(exc, (exceptions.NotAuthenticated, exceptions.AuthenticationFailed)): # WWW-Authenticate header for 401 responses, else coerce to 403 auth_header = self.get_authenticate_header(self.request) if auth_header: exc.auth_header = auth_header else: exc.status_code = status.HTTP_403_FORBIDDEN #被403返回"
"apiview使用raise报错 listapivie 1.本身的代码 # 1.是否使用优惠卷 if discount_id: # 从本身的优惠卷中查找优惠卷 discount_object = models.Userdicount.objects.filter(user=request.user, status=1, dis_id=discount_id).first() if not discount_object: 正常返回错误信息 return Response(""没有此优惠卷"") 返回源码流程的错误信息 # return exceptions.ValidationError(""没有此优惠卷"") 2.简略源码流程 def dispatch(self, request, *args, **kwargs): “,......省略”“” self.response = self.finalize_response(request, response, *args, **kwargs) return self.response 3.finalize_response def finalize_response(self, request, response, *args, **kwargs): """""" Returns the final response object. """""" # Make the error obvious if a proper response is not returned assert isinstance(response, HttpResponseBase), ( 'Expected a `Response`, `HttpResponse` or `HttpStreamingResponse` ' 'to be returned from the view, but received a `%s`' % type(response) ) if isinstance(response, Response): if not getattr(request, 'accepted_renderer', None): neg = self.perform_content_negotiation(request, force=True) request.accepted_renderer, request.accepted_media_type = neg response.accepted_renderer = request.accepted_renderer response.accepted_media_type = request.accepted_media_type response.renderer_context = self.get_renderer_context() # Add new vary headers to the response instead of overwriting. vary_headers = self.headers.pop('Vary', None) if vary_headers is not None: patch_vary_headers(response, cc_delim_re.split(vary_headers)) for key, value in self.headers.items(): response[key] = value return response"
1.序列化器就可使用 class UserAddModelSerializer(serializers.ModelSerializer): """""" 用户添加优惠卷 """""" # 领取的优惠卷要进行减法运算 remain = serializers.SerializerMethodField() class Meta: model = models.Userdicount fields = ['dis', ""ord"", ""remain""] def validate_dis(self, value): user_object = self.context['request'].user print(""优惠卷的判断的值"", value) # 优惠券不存在 if not value or value.deleted: raise exceptions.ValidationError('优惠券不存在') # 优惠券状态必须是领取中 if value.status != 2: raise exceptions.ValidationError('优惠券不可领取') # 优惠券个数是否合法 if (value.use_count + 1) > value.total_count: raise exceptions.ValidationError('优惠券已领完') # 是否已领取优惠券 exists = models.Userdicount.objects.filter(user=user_object, dis=value).exists() if exists: raise exceptions.ValidationError('优惠券已经领取过,不可重复领取') return value 2.源码流程 for field in fields: validate_method = getattr(self, 'validate_' + field.field_name, None) primitive_value = field.get_value(data) try: validated_value = field.run_validation(primitive_value) if validate_method is not None: validated_value = validate_method(validated_value) except ValidationError as exc: errors[field.field_name] = exc.detail 3.ValidationError class ValidationError(APIException): status_code = status.HTTP_400_BAD_REQUEST #序列化器能够完美返回错误信息和badrequest default_detail = _('Invalid input.') default_code = 'invalid' def __init__(self, detail=None, code=None): if detail is None: detail = self.default_detail if code is None: code = self.default_code # For validation failures, we may collect many errors together, # so the details should always be coerced to a list if not already. if not isinstance(detail, dict) and not isinstance(detail, list): detail = [detail] self.detail = _get_error_details(detail, code)"