Django model怎么自定义指定主键

发布时间:2021-07-12 11:05:15 作者:chen
来源:亿速云 阅读:857
# Django model怎么自定义指定主键

## 前言

在Django的ORM框架中,默认情况下每个模型(Model)都会自动生成一个名为`id`的自增主键字段。但在实际开发中,我们经常需要根据业务需求自定义主键字段。本文将详细介绍如何在Django模型中自定义指定主键,包括使用已有字段作为主键、自定义主键类型以及相关注意事项。

---

## 一、默认主键行为

当不显式指定主键时,Django会自动为模型添加以下字段:

```python
id = models.AutoField(primary_key=True)

这是一个自增的整数类型字段,从1开始递增。这种设计在大多数情况下都能满足需求,但在以下场景可能需要自定义主键:

  1. 需要使用业务相关字段作为主键(如用户手机号)
  2. 需要使用非整数类型的主键(如UUID)
  3. 需要与已有数据库表结构兼容

二、自定义主键的三种方式

1. 使用已有字段作为主键

只需在某个字段参数中设置primary_key=True即可:

from django.db import models

class Student(models.Model):
    student_id = models.CharField(max_length=20, primary_key=True)
    name = models.CharField(max_length=100)
    
    def __str__(self):
        return self.name

注意点: - 设置primary_key=True后,Django不会再自动创建id字段 - 该字段将自动具有null=Falseunique=True的约束 - 主键字段不可修改(除非先删除再重新创建)

2. 使用UUID作为主键

适用于分布式系统或需要隐藏数据量的场景:

import uuid
from django.db import models

class Book(models.Model):
    id = models.UUIDField(
        primary_key=True,
        default=uuid.uuid4,
        editable=False
    )
    title = models.CharField(max_length=200)

优势: - 全局唯一性 - 无需中央节点生成 - 隐藏数据规模信息

3. 使用复合主键

Django官方不直接支持复合主键,但可以通过两种方式模拟:

方式一:使用unique_together约束

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE)
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    quantity = models.PositiveIntegerField()

    class Meta:
        unique_together = [['order', 'product']]

方式二:使用第三方包django-compositekey,但可能影响Django的兼容性


三、主键类型选择指南

主键类型 适用场景 注意事项
AutoField 简单应用、单机系统 默认类型,无需额外配置
UUIDField 分布式系统、需要隐藏ID连续性 存储空间较大(16字节)
CharField 有业务意义的自然键(如ISBN号) 需确保唯一性和不可变性
BigAutoField 超过21亿条记录的预期 Django3.2+新增

四、实际开发中的注意事项

  1. 性能考虑

    • 整数主键的索引效率通常高于字符串
    • UUID虽然避免了自增ID的缺点,但会导致索引碎片化
  2. 迁移问题

    # 修改主键类型需要谨慎处理迁移
    python manage.py makemigrations
    python manage.py migrate
    
  3. Admin集成: 自定义主键后,admin界面可能需要额外配置:

    @admin.register(Book)
    class BookAdmin(admin.ModelAdmin):
       readonly_fields = ('id',)  # 防止修改主键
    
  4. 序列化问题: UUID等非整数主键需要确保API序列化器正确处理:

    class BookSerializer(serializers.ModelSerializer):
       class Meta:
           model = Book
           fields = ['id', 'title']
    

五、总结

Django提供了灵活的主键自定义方案,开发者可以根据实际需求选择: - 简单应用保持默认AutoField即可 - 分布式系统推荐UUIDField - 业务实体可使用自然键作为主键 - 复合主键可通过unique_together模拟

合理的主键设计不仅能满足业务需求,还能提升数据库性能。建议在项目初期就明确主键策略,避免后期修改带来的复杂迁移工作。

最佳实践:除非有明确需求,否则建议优先使用默认自增ID,因其在简单性、存储效率和索引性能上都有优势。 “`

这篇文章共计约900字,采用Markdown格式编写,包含了代码示例、表格对比和注意事项等实用内容,符合技术文档的写作规范。

推荐阅读:
  1. Django 框架4:ORM高级操作-多表定义与操作
  2. Django使用多数据库For python3

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

django

上一篇:es搜索优化和mysql查询优化

下一篇:如何解决spring websocket自动断开连接再创建引发的问题

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》