1,批量在django中插入数据

2,

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)
View Code

 3,使用python打开文件时,经常会遇到各式各样的问题,在这里推荐一个模块codecs,避免很多编码的繁琐工作

import codecs

f = codecs.open('article.json,"w", encoding='utf-8')

posted on 2018-08-28 23:34  人生苦短use,what?  阅读(134)  评论(0编辑  收藏  举报