1,批量在django中插入数据
2,
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from django.db import models from datetime import datetime from django.db import transaction from archive.models import Customer from health.models import SystemDict # Create your models here. ACCOUNT_TYPE_LIST = ((1, '押金账户'), (2, '会员费账户'), (3, '月费账户'), (4, '一卡通')) class IncomeModel(models.Model): class Meta: abstract = True create_time = models.DateTimeField('创建时间', auto_now_add=True, null=True, blank=True) update_time = models.DateTimeField('更新时间', auto_now=True, null=True, blank=True) create_user_id = models.IntegerField('创建用户Id', null=True, blank=True) create_user_name = models.CharField('创建用户', max_length=20, null=True, blank=True) update_user_id = models.IntegerField('更新用户Id', null=True, blank=True) update_user_name = models.CharField('更新用户', max_length=20, null=True, blank=True) enable = models.CharField('是否有效', max_length=20, default=True) class Account(IncomeModel): class Meta: verbose_name = '长者账户' verbose_name_plural = verbose_name db_table = 'income_account' customer = models.ForeignKey(Customer, verbose_name='长者', on_delete=models.PROTECT) account_type = models.ForeignKey(SystemDict, models.CASCADE, 'account_type', verbose_name='账户类型', limit_choices_to={'group_name': 'account_type'}, null=True, blank=True) vcan_card = models.CharField('一卡通卡号', max_length=60, null=True, blank=True) balance = models.DecimalField('账户余额', decimal_places=2, max_digits=10, default=0) def __str__(self): return '{} {} ¥{}'.format(self.customer, self.account_type, self.balance) class RechargeRecord(IncomeModel): recharge_type_list = ((1, '现金'), (2, '银行卡'), (3, '支付宝'), (4, '微信'), (5, '其他')) class Meta: verbose_name = '账户充值' verbose_name_plural = verbose_name db_table = 'income_recharge_records' account = models.ForeignKey(Account, verbose_name='长者账户', on_delete=models.PROTECT, null=True, default=True) amount = models.DecimalField('充值金额', decimal_places=2, max_digits=10) execution_time = models.DateTimeField(verbose_name='充值时间', default=datetime.now) recharge_type = models.IntegerField('充值方式', choices=recharge_type_list) remark = models.CharField('备注', max_length=256, null=True, blank=True) def save(self, force_insert=False, force_update=False, using=None, update_fields=None): with transaction.atomic(): self.account.balance += self.amount self.account.save() super().save(force_insert=False, force_update=False, using=None, update_fields=None) class PayType(IncomeModel): type_group_list = ((0, '实际类型'), (1, '发票类型'), (2, '对应类型')) class Meta: verbose_name = '收费类型' verbose_name_plural = verbose_name db_table = 'income_paytype' type_name = models.CharField('类型名称', max_length=128) type_group = models.IntegerField('类型分组', choices=type_group_list, null=True, blank=True) parent_type_id = models.ForeignKey('self', null=True, blank=True, on_delete=models.PROTECT) def __str__(self): return self.type_name class PayItem(IncomeModel): class Meta: verbose_name = '收费项目' verbose_name_plural = verbose_name db_table = 'income_payitems' item_name = models.CharField('项目名称', max_length=128) real_type = models.ForeignKey(PayType, models.PROTECT, 'real_type', null=True, blank=True, verbose_name='实际类型', limit_choices_to={'type_group': 0}) invoice_type = models.ForeignKey(PayType, models.PROTECT, 'invoice_type', null=True, blank=True, verbose_name='发票类型', limit_choices_to={'type_group': 1}) medical_item = models.ManyToManyField('self', models.PROTECT, null=True, blank=True, verbose_name='医疗项目') price = models.DecimalField('参考价格(元)', null=True, blank=True, decimal_places=2, max_digits=10) def __str__(self): return '{} {} ¥{}'.format(self.real_type, self.item_name, self.price) class Bill(IncomeModel): class Meta: verbose_name = '长者账单' verbose_name_plural = verbose_name customer = models.ForeignKey(Customer, on_delete=models.PROTECT, verbose_name='长者', null=True, blank=True) account = models.ForeignKey(Account, on_delete=models.PROTECT, verbose_name='账户', null=True, blank=True) pay_type = models.ForeignKey(SystemDict, models.CASCADE, 'pay_type', verbose_name='支付方式', limit_choices_to={'group_name': 'pay_type'}, null=True, blank=True) vcan_card = models.CharField('一卡通', max_length=60, null=True, blank=True) pay_item = models.ForeignKey(PayItem, null=True, blank=True, on_delete=models.PROTECT, verbose_name='缴费项目') receivable = models.DecimalField('应收', decimal_places=2, max_digits=10) official_receipts = models.DecimalField('实收', decimal_places=2, max_digits=10) discount_amount = models.DecimalField('优惠金额', decimal_places=2, max_digits=10) remark = models.TextField('备注', max_length=256, null=True, blank=True) fm_name = models.CharField('家属姓名', max_length=128, null=True, blank=True) def save(self, force_insert=False, force_update=False, using=None, update_fields=None): with transaction.atomic(): # 编辑时,查找旧数据 if self.id is not None: old_bill = Bill.objects.filter(id=self.id).first() old_official_receipts = old_bill.official_receipts # 删除旧的账单明细 BillDetail.objects.filter(bill__id=self.id).delete() else: old_official_receipts = 0 self.receivable = self.pay_item.price # 应收减实收,计算优惠金额 self.discount_amount = self.receivable - self.official_receipts # 一卡通刷卡 if self.pay_type.dict_key == '1' : # 没有选择账户,则根据一卡通卡号自动匹配账户 if self.account is None: account = Account.objects.filter(vcan_card=self.vcan_card).first() if account is None: raise RuntimeError('一卡通账户不存在') else: self.account = account if self.vcan_card != self.account.vcan_card: raise RuntimeError('账号选择有误') if self.account.customer.name != self.customer.name: raise RuntimeError('姓名与账户姓名不符') if self.official_receipts > self.account.balance: raise RuntimeError('账户余额不足') # 扣除一卡通账户余额 self.account.balance = self.account.balance + old_official_receipts - self.official_receipts self.account.save() super().save(force_insert=force_insert, force_update=force_update, using=using, update_fields=update_fields) # 查询收费项目中,对应的多个医疗项目 for medical_item in self.pay_item.medical_item.all(): # 将每个医疗项目存储到BillDetail中 bill_detail = BillDetail() bill_detail.bill = self bill_detail.payitem_id = medical_item.id bill_detail.payitem_name = medical_item.item_name bill_detail.payitem_price = medical_item.price bill_detail.real_type = medical_item.real_type bill_detail.invoice_type = medical_item.invoice_type bill_detail.save() def __str__(self): return '零单服务' class BillDetail(IncomeModel): class Meta: verbose_name = '账单明细' verbose_name_plural = verbose_name db_table = 'income_bill_detail' bill = models.ForeignKey(Bill, on_delete=models.CASCADE, verbose_name='账单') payitem_id = models.IntegerField('医疗项目Id', null=True, blank=True) payitem_name = models.CharField('医疗项目名称', max_length=64, null=True, blank=True) payitem_price = models.DecimalField('医疗项目费用', max_digits=10, decimal_places=2, null=True, blank=True) real_type = models.CharField('实际类型', max_length=32, null=True, blank=True) invoice_type = models.CharField('发票类型', max_length=32, null=True, blank=True) def __str__(self): return '{} {}'.format(self.payitem_name, self.payitem_price)
3,使用python打开文件时,经常会遇到各式各样的问题,在这里推荐一个模块codecs,避免很多编码的繁琐工作
import codecs
f = codecs.open('article.json,"w", encoding='utf-8')