class ChargingGunInline(object): """ 枪口信息 """ model = ChargingGun extra = 1 # exclude = ['out_trade_no'] style = "accordion" # readonly_fields = ['qrcode'] form_layout = ( Fieldset( '枪口信息', Row('gun_num', 'charg_status'), Row('gun_type', 'nationalstandard'), Row( AppendedText('voltage_upper_limits', 'V'), AppendedText('voltage_lower_limits', 'V'), ), Row( AppendedText('current', 'A'), AppendedText('power', 'KW'), ), Row('work_status', None), Row('cc_status', 'cp_status'), Row('gun_temp_status', 'elec_lock_status'), Row('relay_status', 'fuse_status'), Row('gun_temp', 'cab_temp'), ), Fieldset( '其他信息', Row('subscribe_min', 'qrcode'), ), )
class HostAdmin(object): def open_web(self, instance): return "<a href='http://%s' target='_blank'>Open</a>" % instance.ip open_web.short_description = "Acts" open_web.allow_tags = True open_web.is_column = True list_display = ('name', 'idc', 'guarantee_date', 'service_type', 'status', 'open_web', 'description') list_display_links = ('name',) raw_id_fields = ('idc',) style_fields = {'system': "radio-inline"} search_fields = ['name', 'ip', 'description'] list_filter = ['idc', 'guarantee_date', 'status', 'brand', 'model', 'cpu', 'core_num', 'hard_disk', 'memory', 'service_type'] list_bookmarks = [{'title': "Need Guarantee", 'query': {'status__exact': 2}, 'order': ('-guarantee_date',), 'cols': ('brand', 'guarantee_date', 'service_type')}] show_detail_fields = ('idc',) list_editable = ( 'name', 'idc', 'guarantee_date', 'service_type', 'description') save_as = True aggregate_fields = {"guarantee_date": "min"} form_layout = ( Main( TabHolder( Tab('Comm Fiels', Fieldset('Company data', 'name', 'idc', description="some comm fields, required" ), Inline(MaintainLog), ), Tab('Extend Fiedls', Fieldset('Contact details', 'service_type', Row('brand', 'model'), Row('cpu', 'core_num'), Row(AppendedText( 'hard_disk', 'G'), AppendedText('memory', "G")), 'guarantee_date' ), ), ), ), Side( Fieldset('Status data', 'status', 'ssh_port', 'ip' ), ) ) inlines = [MaintainInline] reversion_enable = True
class UserInfoAdmin(object): """ 充电(微信)用户 """ list_display = [ 'name', 'nickname', 'openid', 'telephone', 'car_type', 'total_money', 'consume_money', 'account_balance', 'is_freeze', 'balance_reset' ] search_fields = [ 'name', 'openid', 'telephone', 'nickname', 'pile_sn', 'car_type' ] list_filter = ['user_type', 'seller'] list_per_page = 50 reversion_enable = True use_related_menu = False style_fields = {"is_freeze": "radio-inline"} model_icon = 'fa fa-weixin' object_list_template = "wxchat/userinfo_model_list.html" form_layout = (Main( Fieldset('', Row('name', 'nickname'), Row('user_type', 'telephone'), Row('seller', 'openid'), Row('car_number', 'car_type'), Row('id_card', None), css_class='unsort no_title'), Fieldset( "微信公众号信息", 'subscribe', 'subscribe_time', Row('sex', 'subscribe_scene'), Row('country', 'province'), Row('city', 'language'), Row('headimgurl', 'qr_scene'), ), Fieldset( "其他信息", Row('last_charg_time', 'out_trade_no'), Row('visit_city', 'visit_time'), Row('is_freeze', 'freeze_time'), 'freeze_reason', )), Side( AppendedText('total_money', '元'), AppendedText('consume_money', '元'), AppendedText('binding_amount', '元'), AppendedText('consume_amount', '元'), ))
class ParkingFeeOrderAdmin(object): list_display = [ 'out_trade_no', 'name', 'station_name', 'pile_name', 'gun_num', 'begin_time', 'end_time', 'park_fee', 'status' ] search_fields = ['out_trade_no', 'charg_pile__pile_sn', 'name', 'openid'] list_filter = ['seller', 'station', 'charg_pile', 'begin_time', 'status'] exclude = ['seller', 'station', 'charg_pile'] list_per_page = 50 model_icon = 'fa fa-file-text' show_all_rel_details = False readonly_fields = ["balance"] relfield_style = 'fk_ajax' form_layout = (Main( Fieldset( '订单信息', Row('out_trade_no', 'name'), Row('seller_name', 'station_name'), Row('pile_name', 'gun_num'), Row( 'openid', AppendedText('park_fee', '元'), ), Row( 'begin_time', 'end_time', ), Row( 'balance', 'status', ), ), ), ) def queryset(self): queryset = super(ParkingFeeOrderAdmin, self).queryset() if self.request.user.station: return queryset.filter(station=self.request.user.station) elif self.request.user.seller: return queryset.filter(seller=self.request.user.seller) else: return queryset def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'charg_pile': if self.request.user.is_superuser: pass elif self.request.user.station: kwargs['queryset'] = ChargingPile.objects.filter( station=self.request.user.station) elif self.request.user.seller: kwargs['queryset'] = ChargingPile.objects.filter( station__seller=self.request.user.seller) return super(ParkingFeeOrderAdmin, self).formfield_for_dbfield(db_field, **kwargs)
class GroupClientsAdmin(object): """ 集团大客户 """ list_display = [ 'name', 'contact_man', 'telephone', 'address', 'bank_name', 'account_name', 'account_number', 'tax_number', 'legal_person', ] search_fields = ['name', 'telephone', 'account_name', 'legal_person'] model_icon = 'fa fa-weixin' form_layout = (Main( Fieldset( '基本信息', Row('name', 'telephone'), Row('contact_man', 'address'), Row('legal_person', 'id_card'), ), Fieldset( '公司银行信息', Row('bank_name', 'account_name'), Row('account_number', 'tax_number'), ), Fieldset( '其他信息', Row(AppendedText('subscribe_fee', '元'), AppendedText('occupy_fee', '元')), Row(AppendedText('low_fee', '元'), 'low_restrict'), ), ), Side( Fieldset("优惠方案", "dicount", "is_reduction", AppendedText("purchase_amount", "元"), AppendedText("reduction", "元")), ))
class HostAdmin(object): def open_web(self, instance): return """<a href="http://%s" target="_blank">Open</a>""" % instance.ip open_web.short_description = "Acts" open_web.allow_tags = True open_web.is_column = True list_display = ( "name", "idc", "guarantee_date", "service_type", "status", "open_web", "description", "ip", ) list_display_links = ("name", ) raw_id_fields = ("idc", ) style_fields = {"system": "radio-inline"} search_fields = ["name", "ip", "description", "idc__name"] list_filter = [ "idc", "guarantee_date", "status", "brand", "model", "cpu", "core_num", "hard_disk", "memory", ( "service_type", xadmin.filters.MultiSelectFieldListFilter, ), ] list_quick_filter = ["service_type", {"field": "idc__name", "limit": 10}] # list_quick_filter = ["idc_id"] list_bookmarks = [{ "title": "Need Guarantee", "query": { "status__exact": 2 }, "order": ("-guarantee_date", ), "cols": ("brand", "guarantee_date", "service_type"), }] show_detail_fields = ("idc", ) list_editable = ("name", "idc", "guarantee_date", "service_type", "description", "ip") save_as = True aggregate_fields = {"guarantee_date": "min"} grid_layouts = ("table", "thumbnails") form_layout = (Main( TabHolder( Tab( "Comm Fields", Fieldset( "Company data", "name", "idc", description="some comm fields, required", ), Inline(MaintainLog), ), Tab( "Extend Fields", Fieldset( "Contact details", "service_type", Row("brand", "model"), Row("cpu", "core_num"), Row(AppendedText("hard_disk", "G"), AppendedText("memory", "G")), "guarantee_date"), ), ), ), Side(Fieldset("Status data", "status", "ssh_port", "ip"), )) inlines = [MaintainInline] reversion_enable = True data_charts = { "host_service_type_counts": { 'title': u"Host service type count", "x-field": "service_type", "y-field": ("service_type", ), "option": { "series": { "bars": { "align": "center", "barWidth": 0.8, 'show': True } }, "xaxis": { "aggregate": "count", "mode": "categories" }, }, }, }
class HostAdmin(object): def open_web(self, instance): return "<a href='http://%s' target='_blank'>Open</a>" % instance.ip open_web.short_description = "Acts" open_web.allow_tags = True open_web.is_column = True list_display = ('name', 'idc', 'guarantee_date', 'service_type', 'status', 'open_web', 'description') list_display_links = ('name', ) raw_id_fields = ('idc', ) style_fields = {'system': "radio-inline"} search_fields = ['name', 'ip', 'description'] list_filter = [ 'idc', 'guarantee_date', 'status', 'brand', 'model', 'cpu', 'core_num', 'hard_disk', 'memory', ('service_type', xadmin.filters.MultiSelectFieldListFilter) ] list_quick_filter = ['service_type', {'field': 'idc__name', 'limit': 10}] list_bookmarks = [{ 'title': "Need Guarantee", 'query': { 'status__exact': 2 }, 'order': ('-guarantee_date', ), 'cols': ('brand', 'guarantee_date', 'service_type') }] show_detail_fields = ('idc', ) list_editable = ('name', 'idc', 'guarantee_date', 'service_type', 'description') save_as = True aggregate_fields = {"guarantee_date": "min"} grid_layouts = ('table', 'thumbnails') form_layout = (Main( TabHolder( Tab( 'Comm Fields', Fieldset('Company data', 'name', 'idc', description="some comm fields, required"), Inline(MaintainLog), ), Tab( 'Extend Fields', Fieldset( 'Contact details', 'service_type', Row('brand', 'model'), Row('cpu', 'core_num'), Row(AppendedText('hard_disk', 'G'), AppendedText('memory', "G")), 'guarantee_date'), ), ), ), Side(Fieldset('Status data', 'status', 'ssh_port', 'ip'), )) inlines = [MaintainInline] reversion_enable = True data_charts = { "host_service_type_counts": { 'title': u"Host service type count", "x-field": "service_type", "y-field": ("service_type", ), "option": { "series": { "bars": { "align": "center", "barWidth": 0.8, 'show': True } }, "xaxis": { "aggregate": "count", "mode": "categories" }, }, }, }
class ProductAdmin(object): list_display = ['productName', 'image', 'sellerSku', 'brand', 'status'] list_display_links = ['productName'] list_filter = ('brand', 'series', 'status') search_fields = ('productName', 'sellerSku') show_detail_fields = ['productName'] style_fields = {"accessories": "checkbox-inline"} form_layout = ( Main( TabHolder( Tab( "Product Inf", Fieldset( "Basic Inf", "productName", 'title', "status", 'sellerSku', 'image', # Row( # AppendedText("weight", "G"), # AppendedText("offer", "$") # ), AppendedText("weight", "G"), AppendedText("offer", "$"), 'brand', 'series', 'number', 'target_audience', 'scene', 'designer', 'inf_more', 'slogan', 'features', 'a_description', # description="产品的一些基本信息", )), Tab( "More Inf", Fieldset( "More Inf", 'accessories', ), )), ), # Side( # Fieldset("什么都没有"), # ) ) #设置导出的列 list_export_fields = ("productName", 'title', "status", 'sellerSku') list_per_page = 15 import_export_args = { 'import_resource_class': PustomerResource, # 'export_resource_class': ProductInfoResource, }
class IDCAdmin(object): # 自定义显示列 def open_web(self, instance): return """<a href="http://%s" target="_blank">Open</a>""" % instance.name open_web.short_description = "Acts" open_web.allow_tags = True open_web.is_column = True # 插件 list # 列表显示的字段 默认 ('__str__',) list_display = ('name', 'description', 'create_time', 'contact', 'telphone', 'address', 'customer_id', 'open_web') # 显示修改或查看数据详情连接的列 list_display_links = ('name',) # 点击列表连接后是否转到详情页面 list_display_links_details = False # 是否提前加载关联数据, 使用 ``select_related`` list_select_related = None # 每页显示数据的条数 list_per_page = 50 # 每页最大显示数据的条数 list_max_show_all = 200 # 排除显示的列, 在显示列的设置中不会出现这些被排除的列 list_exclude = () # 搜索的字段, 使用模糊搜索 search_fields = ['name', 'description', 'contact', 'telphone', 'address'] # 是否可以自由搜索. 如果开启自由搜索, 用户可以通过 url 参数来进行特定的搜索, 例如:name__contains=我,默认为 True # 这个会影响到过滤,因为他也规范化了过滤查询内容 # free_query_filter = False # 排序(加‘-’表示降序) # ordering = None # 添加数据时候,一步一步填写数据 wizard_form_list = [ ('第一步', ('name', 'description')), ('第二步', ('contact', 'telphone', 'address')), ('第三步', ('customer_id',)) ] # 过滤器, 系统会自动生成搜索器 list_filter = ['name', ] # list_quick_filter 必须是 list_filter 的一个子集才能工作 list_quick_filter = [{'field': 'name', 'limit': 10}] # 添加过滤(这里是过滤日期) # date_hierarchy = ['date'] # filter_horizontal 从‘多选框’的形式改变为‘过滤器’的方式,水平排列过滤器, # 必须是一个 ManyToManyField类型,且不能用于 ForeignKey字段, # 默认地,管理工具使用``下拉框`` 来展现`` 外键`` 字段 # filter_horizontal = ('authors',) # 同上 filter_horizontal,垂直排列过滤器 # filter_vertical = ['authors', ] # 开启书签功能,默认为 True # show_bookmarks = False # 设置默认书签 # 用户可以在列表页面添加自己的书签, 我们可以设定好一些默认书签 list_bookmarks = [{ 'title': '我是默认书签', # 书签的名称, 显示在书签菜单中 'query': {'name__exact': '123'}, # 过滤参数, 是标准的 queryset 过滤 'order': ('-name',), # 排序参数 'cols': ('name', 'contact'), # 显示的列 'search': 'name' # 搜索参数, 指定搜索的内容 }, ] # 定义数据导出功能,可以导出 Excel, CSV, XML, json 格式('xls', 'csv', 'xml', 'json') list_export = ('xls', 'csv', 'xml', 'json') # 列表定时刷新 # 定义自动刷新列表, 用户可以选择3秒或5秒刷新一次页面 refresh_times = (3, 5) # 显示数据详情 details # 设置哪些字段要显示详细信息的按钮 show_detail_fields = ['name', ] # 自动显示所有关联字段的详细信息, 该属性默认为 True # show_all_rel_details = False # 数据即时编辑 # 使用 Ajax , 无需提交或刷新页面即可完成数据的修改 list_editable = ['name'] # 将ForeignKey字段从‘下拉框’改变为‘文本框’显示 raw_id_fields = ("groups",) # 当 Model 是其他 Model 的 ref model 时,其他 Model 在显示本 Model 的字段时使用的 Field Style # fk-ajax 涉及到外键下拉的时候使用ajax搜索的方式而不是全部列出的方式,比如在分类下拉很多的情况下,这个功能就很好用 relfield_style = 'fk-select' # 图标样式 model_icon = 'fa fa-user-secret' reversion_enable = True # 插件 edit # 是否显示 ``另存为`` 按钮,默认为 False save_as = True # 是否在页面上面显示按钮组,默认为 False,这个测试无效 # save_on_top = True # 字段显示样式 # style_fields = { # "name": "radio-inline", # "contact": "checkbox-inline", # } # 页面 Form 的 Layout 对象,是一个标准的 Crispy Form Layout 对象。 # 使用 Layout 可以方便的定义整个 Form 页面的结构。 form_layout = ( # 主区域 Main( TabHolder( Tab( 'TAB 名字', Fieldset( '名字', # 单行显示字段内容 Row('telphone', 'address'), 'description', # Inline(MaintainLog), # 无效 description='一些说明文字', ), ), Tab( 'TAB 名字 2', Fieldset( '一些名字', Row('telphone', 'address'), Row( AppendedText('customer_id', '描述'), ), # 'create_time' # 无效 ), ), ), ), # 侧边区域 Side( Fieldset('Status data', 'telphone', 'address'), ) ) # 插件 aggregation # 列聚合,在list表格下面会增加一行统计的数据,可用的值: count min max avg sum # aggregate_fields = {'user_count': 'sum', } # 插件 layout # 列表的布局方式,是以表格一行一条的方式还是类似于缩略图的方式展示的 # grid_layouts = ("table", "thumbnails") # actions 属性是一个列表, 包含启用的 Action 的类. 系统已经默认内置了删除数据的 Action, # 可以制作 Action 来实现特定的功能, 例如 MyAction actions = [BatchChangeAction, MyAction, ] # 批处理的字段 batch_fields = ('contact', 'description', 'address', 'customer_id')
class ChargingGunAdmin(object): list_display = ['charg_pile', 'charging_pile_sn', 'gun_num', 'work_status', 'charg_status', 'cc_status', 'cp_status', 'gun_temp_status', 'elec_lock_status', 'relay_status',] search_fields = ['gun_num', 'charg_pile__pile_sn'] list_display_links = ['gun_num', 'charg_pile'] list_filter = ['charg_pile', 'work_status'] model_icon = 'fa fa-sitemap' show_all_rel_details = False # save_as = True # save_on_top = True form_layout = ( Fieldset( '枪口信息', Row('gun_num', 'charg_pile'), Row('gun_type', 'nationalstandard'), Row( AppendedText('voltage_upper_limits', 'V'), AppendedText('voltage_lower_limits', 'V'), ), Row( AppendedText('current', 'A'), AppendedText('power', 'KW'), ), Row('work_status', 'charg_status'), Row('cc_status', 'cp_status'), Row('gun_temp_status', 'elec_lock_status'), Row('relay_status', 'fuse_status'), Row('gun_temp', 'cab_temp'), ), Fieldset( '其他信息', Row('subscribe_min', "qrcode"), ), Fieldset( '最近订单', Row('out_trade_no', 'order_time', ), ), ) def queryset(self): queryset = super(ChargingGunAdmin, self).queryset() if self.request.user.station: return queryset.filter(charg_pile__station=self.request.user.station) elif self.request.user.seller: return queryset.filter(charg_pile__station__seller=self.request.user.seller) else: return queryset def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'charg_pile': if self.request.user.is_superuser: pass elif self.request.user.station: kwargs['queryset'] = ChargingPile.objects.filter(station=self.request.user.station) elif self.request.user.seller: kwargs['queryset'] = ChargingPile.objects.filter(station__seller=self.request.user.seller) return super(ChargingGunAdmin, self).formfield_for_dbfield(db_field, **kwargs) def save_models(self): obj = self.new_obj request = self.request upload_path = obj.qrcode.field.upload_to dirs = os.path.join(settings.MEDIA_ROOT, upload_path) if not os.path.exists(dirs): os.makedirs(dirs) domain_url = settings.ROOT_URL if settings.ROOT_URL else "http://" + request.get_host() # domain_url ="http://" + request.get_host() path = reverse('order-prepay', kwargs={'pile_sn': obj.charg_pile.pile_sn, "gun_num": obj.gun_num}) qrcode_content = '{0}{1}'.format(domain_url, path) image = create_qrcode(qrcode_content) image_url = '{0}_{1}.png'.format(obj.charg_pile.pile_sn, obj.gun_num) image.save(os.path.join(dirs, image_url), quality=100) obj.qrcode = '{0}{1}'.format(upload_path, image_url) return super(ChargingGunAdmin, self).save_models() def charg_pile_choices(self, field, request, params, model, model_admin, field_path): if self.request.user.station: piles = ChargingPile.objects.filter(station_id=self.request.user.station.id).values("id", "name") elif self.request.user.seller: piles = ChargingPile.objects.filter(station__seller_id=self.request.user.seller.id).values("id", "name") else: return field.get_choices(include_blank=False) return list(((pile.get('id'), pile.get('name')) for pile in piles))
class ChargingPileAdmin(object): """ 充电桩管理 """ list_display = ['name', 'pile_sn', 'pile_type', 'station', 'pile_mode', 'business_mode', 'get_work_status'] list_display_links = ('name',) search_fields = ['pile_sn', 'name', 'pile_type', 'station'] exclude = ["qrcode", 'group'] list_filter = ['pile_type', 'station', 'pile_mode', 'business_mode'] readonly_fields = ['user'] model_icon = 'fa fa-sitemap' show_all_rel_details = False # list_editable = ['pile_type', 'pile_sn'] refresh_times = [3, 5] # 计时刷新 save_as = True style_fields = { "low_restrict": "radio-inline", "low_offset": "radio-inline", "subscribe_status": "radio-inline", "occupy_status": "radio-inline", 'sub_status': "radio-inline", 'charg_mode': "radio-inline", } form_layout = ( Main( TabHolder( Tab( '基础信息设置', Fieldset( '基础信息', Row('name', 'pile_type'), Row('pile_sn', 'power'), Row('station', 'pile_mode'), Row('business_mode', 'fireware'), Row('symbol_4g', 'symbol_eth'), 'charg_mode', 'sub_time', Row('is_subsidy', 'faults'), ), Inline(ChargingGun), css_id="base_info", ), Tab( '其他设置', Fieldset( "预约及占位设置", 'charg_policy', Row('subscribe_status', AppendedText('subscribe_fee', '元')), Row('occupy_status', AppendedText('occupy_fee', '元')), ), Fieldset( "小电流设置参数", Row('low_restrict', AppendedText('low_cur_value', '毫安')), Row('low_offset', AppendedText('low_offset_value', '元')), ), Fieldset( "单枪参数", Row(AppendedText('gun_max_voltage', '伏'), AppendedText('gun_min_voltage', '伏')), Row(AppendedText('gun_max_current', '安'), AppendedText('gun_min_current', '安')), ), css_id="other_set", ), ), ), Side( Fieldset("其他信息", 'sub_status', 'user', 'max_gun', 'restart_nums'), ) ) inlines = [ChargingGunInline] def queryset(self): queryset = super(ChargingPileAdmin, self).queryset() if self.request.user.station: return queryset.filter(station=self.request.user.station) elif self.request.user.seller: return queryset.filter(station__seller=self.request.user.seller) else: return queryset def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'station': if not self.request.user.is_superuser: kwargs['queryset'] = Station.objects.filter(seller=self.request.user.seller) return super(ChargingPileAdmin, self).formfield_for_dbfield(db_field, **kwargs) def save_models(self): obj = self.new_obj request = self.request obj.user = request.user obj.group = request.user.groups.first() super(ChargingPileAdmin, self).save_models() def save_related(self): obj = self.new_obj super(ChargingPileAdmin, self).save_related() for inst in obj.charginggun_set.all(): self.save_image(inst) def save_image(self, instance): upload_path = instance.qrcode.field.upload_to dirs = os.path.join(settings.MEDIA_ROOT, upload_path) if not os.path.exists(dirs): os.makedirs(dirs) domain_url = settings.ROOT_URL if settings.ROOT_URL else "http://" + self.request.get_host() # domain_url = "http://" + self.request.get_host() path = reverse('order-prepay', kwargs={'pile_sn': instance.charg_pile.pile_sn, "gun_num": instance.gun_num}) qrcode_content = '{0}{1}'.format(domain_url, path) image = create_qrcode(qrcode_content) image_url = '{0}_{1}.png'.format(instance.charg_pile.pile_sn, instance.gun_num) image.save(os.path.join(dirs, image_url), quality=100) instance.qrcode = '{0}{1}'.format(upload_path, image_url) instance.save() def station_choices(self, field, request, params, model, model_admin, field_path): if self.request.user.station: stations = Station.objects.filter(id=self.request.user.station.id).values("id", "name") elif self.request.user.seller: stations = Station.objects.filter(seller_id=self.request.user.seller.id).values("id", "name") else: return field.get_choices(include_blank=False) return list(((station.get('id'), station.get('name')) for station in stations))
class StationAdmin(object): list_display = ['id', 'name', 'seller', 'province_city_district', 'address', 'telephone', 'station_status', 'station_type'] list_display_links = ('name',) search_fields = ['name', 'address', 'seller.name', 'telephone', 'telephone1'] list_filter = ['seller', 'dicount'] model_icon = 'fa fa-sitemap' relfield_style = 'fk_ajax' inlines = [StationImageInline] form_layout = ( Main( Fieldset( '基本信息', Row('name', 'seller'), Row('province', 'city'), Row('district', 'address'), Row('equip_owner_id', 'station_status'), Row('station_type', 'construction'), Row('telephone', 'telephone1'), Row('is_show', None), ), Fieldset( '费用收取设置', Row( AppendedText('low_restrict_val', '毫安'), AppendedText('low_fee', '元') ), Row( AppendedText('service_ratio', '%'), AppendedText('rebate_ratio', '%') ), ), Fieldset( '离线情况设置', Row( AppendedText('offline_sub_fee', '元'), AppendedText('offline_occupy_fee', '元'), ), Row( AppendedText('offline_low_fee', '元'), 'offline_low_restrict', ) ), ), Side( Fieldset( '优惠方案', 'dicount', 'is_reduction', AppendedText('purchase_amount', '元'), AppendedText('reduction', '元') ), Fieldset( '地理信息', 'latitude', 'longitude', 'altitude', ), ), ) def get_media(self): media = super(StationAdmin, self).get_media() path = self.request.get_full_path() if "add" in path or 'update' in path: media.add_js([self.static('stationmanager/js/xadmin.areacode.js')]) return media def queryset(self): queryset = super(StationAdmin, self).queryset() if self.request.user.station: return queryset.filter(id=self.request.user.station.id) elif self.request.user.seller: return queryset.filter(seller=self.request.user.seller) else: return queryset def seller_choices(self, field, request, params, model, model_admin, field_path): if self.request.user.station: seller_lst = Seller.objects.filter(id=self.request.user.station.seller.id).values("id", "name") elif self.request.user.seller: seller_lst = Seller.objects.filter(id=self.request.user.seller.id).values("id", "name") else: return field.get_choices(include_blank=False) return list(((seller.get('id'), seller.get('name')) for seller in seller_lst)) def formfield_for_dbfield(self, db_field, **kwargs): # print(self.new_obj) if db_field.name == 'seller': if not self.request.user.is_superuser: kwargs['queryset'] = Seller.objects.filter(id=self.request.user.seller.id) if db_field.name == 'province': kwargs['queryset'] = AreaCode.objects.extra(where=['length(code)=2']) if db_field.name == 'city': kwargs['queryset'] = AreaCode.objects.extra(where=['length(code)=4']) if db_field.name == 'district': kwargs['queryset'] = AreaCode.objects.extra(where=['length(code)=6']) # if db_field.name == 'fee_scale': # kwargs['queryset'] = AreaCode.objects.extra(where=['length(code)=6']) return super(StationAdmin, self).formfield_for_dbfield(db_field, **kwargs)
class CardOrderAdmin(object): list_display = [ 'out_trade_no', 'name', 'charg_mode', 'pile_name', 'gun_num', 'total_minutes', 'total_readings', 'begin_time', 'pay_time', 'consum_money', 'cash_fee', 'status' ] search_fields = ['out_trade_no', 'charg_pile__pile_sn', 'name', 'openid'] list_filter = ['charg_status', 'begin_time', 'status'] exclude = ['charg_type', 'seller', 'station', 'charg_pile'] list_per_page = 50 model_icon = 'fa fa-file-text' show_all_rel_details = False relfield_style = 'fk_ajax' aggregate_fields = {"total_readings": "sum", 'cash_fee': "sum"} form_layout = ( Main( Fieldset( '订单信息', Row('out_trade_no', 'name'), Row('seller_name', 'station_name'), Row('pile_name', 'gun_num'), Row('charg_mode', 'protocol'), Row('start_model', 'openid'), Row( AppendedText('total_fee', '元'), AppendedText('charg_min_val', '分钟'), ), Row( AppendedText('charg_soc_val', '%'), AppendedText('charg_reading_val', '度'), ), ), Fieldset( '充电信息', Row( AppendedText('begin_soc', '%'), AppendedText('end_soc', '%'), ), Row( 'begin_time', 'end_time', ), Row(AppendedText('begin_reading', '度'), AppendedText('end_reading', '度')), Row( AppendedText('total_readings', 'KWH'), AppendedText('park_fee', '元'), ), Row( AppendedText('power_fee', '元'), AppendedText('service_fee', '元'), ), ), Fieldset( '支付情况', Row( AppendedText('cash_fee', '元'), AppendedText('consum_money', '元'), ), Row( 'transaction_id', 'pay_time', ), Row( 'balance', 'main_openid', ), ), Fieldset( '充电状态信息', Row('charg_status', 'status'), ), ), Side( Fieldset( '车辆信息', 'vin_code', AppendedText('max_current', '安'), AppendedText('max_voltage', '伏'), AppendedText('max_single_voltage', '伏'), AppendedText('max_temp', '度'), ), Fieldset( '其他信息', 'output_voltage', 'output_current', 'prev_reading', 'start_charge_seq', 'report_result', 'report_time', ), ), ) def queryset(self): queryset = super().queryset() if self.request.user.station: return queryset.filter(station=self.request.user.station, start_model=1) elif self.request.user.seller: return queryset.filter(seller=self.request.user.seller, start_model=1) else: return queryset.filter(start_model=1) def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'charg_pile': if self.request.user.is_superuser: pass elif self.request.user.station: kwargs['queryset'] = ChargingPile.objects.filter( station=self.request.user.station) elif self.request.user.seller: kwargs['queryset'] = ChargingPile.objects.filter( station__seller=self.request.user.seller) return super().formfield_for_dbfield(db_field, **kwargs) def has_add_permission(self): return False def has_change_permission(self, obj=None): return False def has_delete_permission(self, obj=None): return False
class OrderRecordAdmin(object): def charg_time(self, obj): if obj.begin_time is None or obj.end_time is None: return 0 else: # return int((obj.end_time - obj.begin_time).seconds / 60) mins = decimal.Decimal( (obj.end_time - obj.begin_time).total_seconds() / 60) return mins.quantize(decimal.Decimal('0.01')) charg_time.short_description = '充电时间(分)' charg_time.allow_tags = True charg_time.is_column = True def meter_quantity(self, obj): return obj.end_reading - obj.begin_reading meter_quantity.short_description = '充电电量(度)' meter_quantity.allow_tags = True meter_quantity.is_column = True def power_money(self, obj): return ((obj.end_reading - obj.begin_reading) * obj.price).quantize( decimal.Decimal("0.01")) power_money.short_description = '电费金额(元)' power_money.allow_tags = True power_money.is_column = True def service_money(self, obj): return ((obj.end_reading - obj.begin_reading) * obj.service_price).quantize(decimal.Decimal("0.01")) service_money.short_description = '服务费金额(元)' service_money.allow_tags = True service_money.is_column = True list_display = [ 'out_trade_no', 'pile_sn', 'gun_num', 'charg_time', 'meter_quantity', 'price', 'service_price', 'accumulated_readings', 'accumulated_amount', 'accumulated_service_amount' ] search_fields = ['out_trade_no'] exclude = ["price_begin_time", "price_end_time", "order"] readonly_fields = [ 'charg_time', 'meter_quantity', 'accumulated_service_amount', 'accumulated_readings', 'accumulated_amount' ] date_hierarchy = 'begin_time' list_per_page = 30 model_icon = 'fa fa-file-text' form_layout = ( Fieldset( '订单信息', Row('out_trade_no', 'pile_sn'), Row('serial_num', None), Row('gun_num', "current_soc"), ), Fieldset( '充电信息', Row( 'begin_time', AppendedText('begin_reading', '度'), ), Row( 'end_time', AppendedText('end_reading', '度'), ), Row(AppendedText('price', '元/度'), AppendedText('service_price', '元/度')), Row('charg_time', 'meter_quantity', 'accumulated_readings', 'accumulated_amount', 'accumulated_service_amount'), ), ) def queryset(self): queryset = super(OrderRecordAdmin, self).queryset() if self.request.user.station: return queryset.filter(station_id=self.request.user.station_id) elif self.request.user.seller: return queryset.filter(seller_id=self.request.user.seller_id) else: return queryset
class OrderAdmin(object): list_display = [ 'out_trade_no', 'name', 'charg_mode', 'station_name', 'pile_name', 'gun_num', 'car_type', 'total_minutes', 'total_readings', 'begin_time', 'pay_time', 'consum_money', 'power_fee', 'service_fee', 'cash_fee', 'charg_status', 'status', 'report_result', 'curve' ] search_fields = [ 'out_trade_no', 'charg_pile__pile_sn', 'name', 'openid', 'car_type' ] list_filter = [ 'seller', 'station', 'charg_pile', 'charg_mode', 'charg_status', 'begin_time', 'status', 'report_result' ] exclude = ['charg_type', 'seller', 'station', 'charg_pile'] date_hierarchy = 'begin_time' list_per_page = 50 model_icon = 'fa fa-file-text' show_all_rel_details = False readonly_fields = ["balance", "main_openid"] relfield_style = 'fk_ajax' aggregate_fields = { "total_readings": "sum", 'consum_money': "sum", 'cash_fee': "sum", 'power_fee': "sum", "service_fee": "sum" } object_list_template = "chargingorder/order_model_list.html" form_layout = ( Main( Fieldset( '订单信息', Row('out_trade_no', 'name'), Row('seller_name', 'station_name'), Row('pile_name', 'gun_num'), Row('charg_mode', 'protocol'), Row('start_model', 'openid'), Row( AppendedText('total_fee', '元'), AppendedText('charg_min_val', '分钟'), ), Row( AppendedText('charg_soc_val', '%'), AppendedText('charg_reading_val', '度'), ), ), Fieldset( '充电信息', Row( AppendedText('begin_soc', '%'), AppendedText('end_soc', '%'), ), Row( 'begin_time', 'end_time', ), Row(AppendedText('begin_reading', '度'), AppendedText('end_reading', '度')), Row( AppendedText('total_readings', 'KWH'), AppendedText('park_fee', '元'), ), Row( AppendedText('power_fee', '元'), AppendedText('service_fee', '元'), ), ), Fieldset( '支付情况', Row( AppendedText('cash_fee', '元'), AppendedText('consum_money', '元'), ), Row( 'transaction_id', 'pay_time', ), Row( 'balance', 'main_openid', ), ), Fieldset( '充电状态信息', Row('charg_status', 'status'), ), ), Side( Fieldset( '车辆信息', 'car_type', 'vin_code', AppendedText('max_current', '安'), AppendedText('max_voltage', '伏'), AppendedText('max_single_voltage', '伏'), AppendedText('max_temp', '度'), ), Fieldset( '其他信息', 'output_voltage', 'output_current', 'prev_reading', 'start_charge_seq', 'report_result', 'report_time', ), ), ) def curve(self, obj): curve_url = reverse("order-detail-list", kwargs={"out_trade_no": obj.out_trade_no}) refund_btn = "<a class='btn btn-xs btn-primary' data-toggle='modal' data-target='#myModal' " \ "data-uri='{}'>监控曲线</a>".format(curve_url) return refund_btn curve.short_description = "充电监控" curve.allow_tags = True curve.is_column = True def queryset(self): queryset = super(OrderAdmin, self).queryset() if self.request.user.station: return queryset.filter(station=self.request.user.station) elif self.request.user.seller: return queryset.filter(seller=self.request.user.seller) else: return queryset def formfield_for_dbfield(self, db_field, **kwargs): if db_field.name == 'charg_pile': if self.request.user.is_superuser: pass elif self.request.user.station: kwargs['queryset'] = ChargingPile.objects.filter( station=self.request.user.station) elif self.request.user.seller: kwargs['queryset'] = ChargingPile.objects.filter( station__seller=self.request.user.seller) return super(OrderAdmin, self).formfield_for_dbfield(db_field, **kwargs) def get_media(self): media = super(OrderAdmin, self).get_media() # path = self.request.get_full_path() # if "add" in path or 'update' in path: media.add_js([self.static('stationmanager/js/xadmin.areacode.js')]) return media
class UnusualOrderAdmin(object): list_display = [ 'out_trade_no', 'name', 'charg_mode', 'station_name', 'pile_name', 'gun_num', 'car_type', 'total_minutes', 'total_readings', 'begin_time', 'consum_money', 'power_fee', 'service_fee', 'charg_status', 'curve' ] search_fields = ['out_trade_no', 'charg_pile__pile_sn', 'name', 'openid'] list_filter = ['charg_status', 'begin_time', 'status'] exclude = ['charg_type', 'seller', 'station', 'charg_pile'] list_per_page = 50 model_icon = 'fa fa-file-text' show_all_rel_details = False relfield_style = 'fk_ajax' object_list_template = "chargingorder/order_model_list.html" form_layout = ( Main( Fieldset( '订单信息', Row('out_trade_no', 'name'), Row('seller_name', 'station_name'), Row('pile_name', 'gun_num'), Row('charg_mode', 'protocol'), Row('start_model', 'openid'), Row( AppendedText('total_fee', '元'), AppendedText('charg_min_val', '分钟'), ), Row( AppendedText('charg_soc_val', '%'), AppendedText('charg_reading_val', '度'), ), ), Fieldset( '充电信息', Row( AppendedText('begin_soc', '%'), AppendedText('end_soc', '%'), ), Row( 'begin_time', 'end_time', ), Row(AppendedText('begin_reading', '度'), AppendedText('end_reading', '度')), Row( AppendedText('total_readings', 'KWH'), AppendedText('park_fee', '元'), ), Row( AppendedText('power_fee', '元'), AppendedText('service_fee', '元'), ), ), Fieldset( '支付情况', Row( AppendedText('cash_fee', '元'), AppendedText('consum_money', '元'), ), Row( 'transaction_id', 'pay_time', ), Row( 'balance', 'main_openid', ), ), Fieldset( '充电状态信息', Row('charg_status', 'status'), ), ), Side( Fieldset( '车辆信息', 'car_type', 'vin_code', AppendedText('max_current', '安'), AppendedText('max_voltage', '伏'), AppendedText('max_single_voltage', '伏'), AppendedText('max_temp', '度'), ), Fieldset( '其他信息', 'output_voltage', 'output_current', 'prev_reading', 'start_charge_seq', 'report_result', 'report_time', ), ), ) def queryset(self): queryset = super().queryset() if self.request.user.station: return queryset.filter(station=self.request.user.station).filter( Q(total_readings=0) & Q(status=2) | Q(charg_status__fault=1)) elif self.request.user.seller: return queryset.filter(seller=self.request.user.seller).filter( Q(total_readings=0) & Q(status=2) | Q(charg_status__fault=1)) else: return queryset.filter( Q(total_readings=0) & Q(status=2) | Q(charg_status__fault=1)) def has_add_permission(self): return False def has_change_permission(self, obj=None): return False def has_delete_permission(self, obj=None): return False def curve(self, obj): curve_url = reverse("order-detail-list", kwargs={"out_trade_no": obj.out_trade_no}) refund_btn = "<a class='btn btn-xs btn-primary' data-toggle='modal' data-target='#myModal' " \ "data-uri='{}'>监控曲线</a>".format(curve_url) return refund_btn curve.short_description = "充电监控" curve.allow_tags = True curve.is_column = True