时间:2021-05-23
1.django自定义字段类型,实现非主键字段的自增
# -*- encoding: utf-8 -*-from django.db.models.fields import Field, IntegerFieldfrom django.core import checks, exceptionsfrom 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 None2.使用
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外键(跨表操作):
跨表操作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'])
前端:
<td>{{ row.b__caption }}</td> # 用双下划线做跨表操作
以上这篇django自定义非主键自增字段类型详解(auto increment field)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
MySQL序列AUTO_INCREMENT详解及实例代码MySQL序列是一组整数:1,2,3,...,由于一张数据表只能有一个字段自增主键,如果你想实现其他字段
mysql使用auto_increment的语法实现表字段自增。在PostgreSQL中,具有数据类型为smallserial,serial,bigserial
mysql中的自增auto_increment功能相信每位phper都用过,也都知道如何设置字段为自增字段,但并不是所有phper都知道auto_increme
在mysql中很多朋友都认为字段为AUTO_INCREMENT类型自增ID值是无法修改,其实这样理解是错误的,下面介绍mysql自增ID的起始值修改与设置方法。
一、mysql获取当前字段最大idSQL语句:selectmax(id)fromyourtable;二、获取mysql表自增(Auto_increment)值A