热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

ef设置非自增长id_django自定义非主键自增字段类型详解(autoincrementfield)

1.django自定义字段类型,实现非主键字段的自增#-*-encoding:utf-8-*-fromdjango.db.models.fieldsimportField,Inte

1.django自定义字段类型,实现非主键字段的自增

# -*- encoding: utf-8 -*-

from django.db.models.fields import Field, IntegerField

from django.core import checks, exceptions

from django.utils.translation import ugettext_lazy as _

class AutoIncreField(Field):

description = _("Integer")

empty_strings_allowed = False

default_error_messages = {

'invalid': _("'%(value)s' value must be an integer."),

}

def __init__(self, *args, **kwargs):

kwargs['blank'] = True

super(AutoIncreField, self).__init__(*args, **kwargs)

def check(self, **kwargs):

errors = super(AutoIncreField, self).check(**kwargs)

# 每张表只能设置一个字段为自增长字段,这个字段可以是主键,也可以不是主键,如果不是主键,则必须设置为一种“键(key)”

# (primary key)也是键(key)的一种,key还包括外键(foreign key)、唯一键(unique key)

errors.extend(self._check_key())

return errors

def _check_key(self):

if not self.unique:

return [

checks.Error(

'AutoIncreFields must set key(unique=True).',

obj=self,

id='fields.E100',

),

]

else:

return []

def deconstruct(self):

name, path, args, kwargs = super(AutoIncreField, self).deconstruct()

del kwargs['blank']

kwargs['unique'] = True

return name, path, args, kwargs

def get_internal_type(self):

return "AutoIncreField"

def to_python(self, value):

if value is None:

return value

try:

return int(value)

except (TypeError, ValueError):

raise exceptions.ValidationError(

self.error_messages['invalid'],

code='invalid',

params={'value': value},

)

def db_type(self, connection):

return 'bigint AUTO_INCREMENT'

def rel_db_type(self, connection):

return IntegerField().db_type(connection=connection)

def validate(self, value, model_instance):

pass

def get_db_prep_value(self, value, connection, prepared=False):

if not prepared:

value = self.get_prep_value(value)

value = connection.ops.validate_autopk_value(value)

return value

def get_prep_value(self, value):

value = super(AutoIncreField, self).get_prep_value(value)

if value is None:

return None

return int(value)

def contribute_to_class(self, cls, name, **kwargs):

assert not cls._meta.auto_field, "A model can't have more than one AutoIncreField."

super(AutoIncreField, self).contribute_to_class(cls, name, **kwargs)

cls._meta.auto_field = self

def formfield(self, **kwargs):

return None

2.使用

class Test(models.Model):

id = models.UUIDField(primary_key=True, default=uuid4)

numbering = AutoIncreField(_(u'numbering'), unique=True)

name = models.CharField(_(u'name'), max_length=32, blank=True, null=True)

3.bug

当save()后并不能刷新instance,及save后numbering会为空值,需要重写get一次.

如果您修复了这个问题请留言回复下,谢谢

4.bug修复

以一种非常不优雅的方法进行了简单修复,重写了模型的save方法,在save后从新get

class AutoIncreFieldFixMinxin(object):

def save(self, *args, **kwargs):

super(AutoIncreFieldFixMinxin, self).save(*args, **kwargs)

auto_field = self._meta.auto_field.name

new_obj = self.__class__.objects.get(pk=self.pk)

setattr(self, auto_field, int(getattr(new_obj, auto_field)))

class Test(AutoIncreFieldFixMinxin, models.Model):

id = models.UUIDField(primary_key=True, default=uuid4)

sequence = AutoIncreField(_(u'sequence'), unique=True)

name = models.CharField(_(u'name'), max_length=100)

补充知识:Django model 表与表的关系

一对多:models.ForeignKey(其他表)

多对多:models.ManyToManyField(其他表)

一对一:models.OneToOneField(其他表)

应用场景:

一对多:当一张表中创建一行数据时,有一个单选的下拉框(可以被重复选择)

例如:创建用户信息时候,需要选择一个用户类型【普通用户】【金牌用户】【铂金用户】等。

多对多:在某表中创建一行数据是,有一个可以多选的下拉框

例如:创建用户信息,需要为用户指定多个爱好

一对一:在某表中创建一行数据时,有一个单选的下拉框(下拉框中的内容被用过一次就消失了

例如:原有含10列数据的一张表保存相关信息,经过一段时间之后,10列无法满足需求,需要为原来的表再添加5列数据

ForeignKey(ForeignObject) # ForeignObject(RelatedField)

to, # 要进行关联的表名

to_field=None, # 要关联的表中的字段名称

on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为

- models.CASCADE,删除关联数据,与之关联也删除

- models.DO_NOTHING,删除关联数据,引发错误IntegrityError

- models.PROTECT,删除关联数据,引发错误ProtectedError

- models.SET_NULL,删除关联数据,与之关联的值设置为null(前提FK字段需要设置为可空)

- models.SET_DEFAULT,删除关联数据,与之关联的值设置为默认值(前提FK字段需要设置默认值)

- models.SET,删除关联数据,

a. 与之关联的值设置为指定值,设置:models.SET(值)

b. 与之关联的值设置为可执行对象的返回值,设置:models.SET(可执行对象)

def func():

return 10

class MyModel(models.Model):

user = models.ForeignKey(

to="User",

to_field="id"

on_delete=models.SET(func),)

related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()

related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')

limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:

# 如:

- limit_choices_to={'nid__gt': 5}

- limit_choices_to=lambda : {'nid__gt': 5}

from django.db.models import Q

- limit_choices_to=Q(nid__gt=10)

- limit_choices_to=Q(nid=8) | Q(nid__gt=10)

- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')

db_constraint=True # 是否在数据库中创建外键约束

parent_link=False # 在Admin中是否显示关联数据

OneToOneField(ForeignKey)

to, # 要进行关联的表名

to_field=None # 要关联的表中的字段名称

on_delete=None, # 当删除关联表中的数据时,当前表与其关联的行的行为

###### 对于一对一 ######

# 1. 一对一其实就是 一对多 + 唯一索引

# 2.当两个类之间有继承关系时,默认会创建一个一对一字段

# 如下会在A表中额外增加一个c_ptr_id列且唯一:

class C(models.Model):

nid = models.AutoField(primary_key=True)

part = models.CharField(max_length=12)

class A(C):

id = models.AutoField(primary_key=True)

code = models.CharField(max_length=1)

ManyToManyField(RelatedField)

to, # 要进行关联的表名

related_name=None, # 反向操作时,使用的字段名,用于代替 【表名_set】 如: obj.表名_set.all()

related_query_name=None, # 反向操作时,使用的连接前缀,用于替换【表名】 如: models.UserGroup.objects.filter(表名__字段名=1).values('表名__字段名')

limit_choices_to=None, # 在Admin或ModelForm中显示关联数据时,提供的条件:

# 如:

- limit_choices_to={'nid__gt': 5}

- limit_choices_to=lambda : {'nid__gt': 5}

from django.db.models import Q

- limit_choices_to=Q(nid__gt=10)

- limit_choices_to=Q(nid=8) | Q(nid__gt=10)

- limit_choices_to=lambda : Q(Q(nid=8) | Q(nid__gt=10)) & Q(caption='root')

symmetrical=None, # 仅用于多对多自关联时,symmetrical用于指定内部是否创建反向操作的字段

# 做如下操作时,不同的symmetrical会有不同的可选字段

models.BB.objects.filter(...)

# 可选字段有:code, id, m1

class BB(models.Model):

code = models.CharField(max_length=12)

m1 = models.ManyToManyField('self',symmetrical=True)

# 可选字段有: bb, code, id, m1

class BB(models.Model):

code = models.CharField(max_length=12)

m1 = models.ManyToManyField('self',symmetrical=False)

through=None, # 自定义第三张表时,使用字段用于指定关系表

through_fields=None, # 自定义第三张表时,使用字段用于指定关系表中那些字段做多对多关系表

from django.db import models

class Person(models.Model):

name = models.CharField(max_length=50)

class Group(models.Model):

name = models.CharField(max_length=128)

members = models.ManyToManyField(

Person,

through='Membership',

through_fields=('group', 'person'),

)

class Membership(models.Model):

group = models.ForeignKey(Group, on_delete=models.CASCADE)

person = models.ForeignKey(Person, on_delete=models.CASCADE)

inviter = models.ForeignKey(

Person,

on_delete=models.CASCADE,

related_name="membership_invites",

)

invite_reason = models.CharField(max_length=64)

db_constraint=True, # 是否在数据库中创建外键约束

db_table=None, # 默认创建第三张表时,数据库中表的名称

ForeignKey外键(跨表操作):

跨表操作1

v = models.Host.objects.filter(nid__gt=0)

v[0].b.caption #通过.进行跨表操作,在对象中去做跨表操作用.

跨表操作2

v = models.Host.objects.filter(nid__gt=0).values('nid','hostname','b_id','b__caption') #使用values()取值时可以用双下划线做跨表操作

for row in v:

print(row['nid'],row['hostname'],row['b_id'],row['b__caption'])

前端:

{{ row.b__caption }} # 用双下划线做跨表操作

以上这篇django自定义非主键自增字段类型详解(auto increment field)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。



推荐阅读
  • 本文深入探讨了 MXOTDLL.dll 在 C# 环境中的应用与优化策略。针对近期公司从某生物技术供应商采购的指纹识别设备,该设备提供的 DLL 文件是用 C 语言编写的。为了更好地集成到现有的 C# 系统中,我们对原生的 C 语言 DLL 进行了封装,并利用 C# 的互操作性功能实现了高效调用。此外,文章还详细分析了在实际应用中可能遇到的性能瓶颈,并提出了一系列优化措施,以确保系统的稳定性和高效运行。 ... [详细]
  • 深入解析 UIImageView 与 UIImage 的关键细节与应用技巧
    本文深入探讨了 UIImageView 和 UIImage 的核心特性及应用技巧。首先,详细介绍了如何在 UIImageView 中实现动画效果,包括创建和配置 UIImageView 实例的具体步骤。此外,还探讨了 UIImage 的加载方式及其对性能的影响,提供了优化图像显示和内存管理的有效方法。通过实例代码和实际应用场景,帮助开发者更好地理解和掌握这两个重要类的使用技巧。 ... [详细]
  • 本文探讨了在Android应用中实现动态滚动文本显示控件的优化方法。通过详细分析焦点管理机制,特别是通过设置返回值为`true`来确保焦点不会被其他控件抢占,从而提升滚动文本的流畅性和用户体验。具体实现中,对`MarqueeText.java`进行了代码层面的优化,增强了控件的稳定性和兼容性。 ... [详细]
  • C#中实现高效UDP数据传输技术
    C#中实现高效UDP数据传输技术 ... [详细]
  • 如何使用 net.sf.extjwnl.data.Word 类及其代码示例详解 ... [详细]
  • 深入解析 Django 中用户模型的自定义方法与技巧 ... [详细]
  • 利用C#技术实现Word文档的动态生成与编辑
    本文通过一个简单的示例,介绍了如何使用C#语言实现Word文档的动态生成与编辑功能。文章详细阐述了在项目中引用Word动态库的方法,并通过具体代码示例展示了如何创建和操作Word表格。此内容旨在为初学者提供参考和学习资料,欢迎读者提出宝贵意见和建议。 ... [详细]
  • 使用 MyEclipse 和 TestNG 测试框架在 Java 中高效进行单元测试
    通过MyEclipse集成TestNG测试框架,可以在Java开发中高效地进行单元测试。本文介绍了在JDK 1.8.0_121和MyEclipse 10.0离线环境下配置和使用TestNG的具体步骤,帮助开发者提高测试效率和代码质量。 ... [详细]
  • 本文探讨了如何在C#中实现USB条形码扫描仪的数据读取,并自动过滤掉键盘输入,即使不知道设备的供应商ID(VID)和产品ID(PID)。通过详细的技术指导和代码示例,展示了如何高效地处理条形码数据,确保系统能够准确识别并忽略来自键盘的干扰信号。该方法适用于多种USB条形码扫描仪,无需额外配置设备信息。 ... [详细]
  • 深入解析JWT的实现与应用
    本文深入探讨了JSON Web Token (JWT) 的实现机制及其应用场景。JWT 是一种基于 RFC 7519 标准的开放性认证协议,用于在各方之间安全地传输信息。文章详细分析了 JWT 的结构、生成和验证过程,并讨论了其在现代 Web 应用中的实际应用案例,为开发者提供了全面的理解和实践指导。 ... [详细]
  • 本文作为“实现简易版Spring系列”的第五篇,继前文深入探讨了Spring框架的核心技术之一——控制反转(IoC)之后,将重点转向另一个关键技术——面向切面编程(AOP)。对于使用Spring框架进行开发的开发者来说,AOP是一个不可或缺的概念。了解AOP的背景及其基本原理,对于掌握这一技术至关重要。本文将通过具体示例,详细解析AOP的实现机制,帮助读者更好地理解和应用这一技术。 ... [详细]
  • 本文将详细介绍在Android应用中添加自定义返回按钮的方法,帮助开发者更好地理解和实现这一功能。通过具体的代码示例和步骤说明,本文旨在为初学者提供清晰的指导,确保他们在开发过程中能够顺利集成返回按钮,提升用户体验。 ... [详细]
  • Spring框架入门指南:专为新手打造的详细学习笔记
    Spring框架是Java Web开发中广泛应用的轻量级应用框架,以其卓越的功能和出色的性能赢得了广大开发者的青睐。本文为初学者提供了详尽的学习指南,涵盖基础概念、核心组件及实际应用案例,帮助新手快速掌握Spring框架的核心技术与实践技巧。 ... [详细]
  • 探讨String参数作为锁对象时,实际锁定的是哪个具体实例? ... [详细]
  • 从 Java 过渡到 Ruby,不仅是一次编程语言的转换,更是一段技术进阶的旅程。本文将深入探讨两种语言在语法、生态系统和开发模式上的差异,帮助开发者顺利实现转型,并在新的环境中高效地编写高质量代码。 ... [详细]
author-avatar
leban
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有