You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django自定义自增主键遇UUID验证错误及数据丢失问题求助

Let's walk through what's going wrong here and fix it step by step:

First Issue: UUID Validation Failed

You defined id as a UUIDField, but your get_next() function returns plain integers like 1, 2, 3. UUID fields require values in a specific UUID format (e.g., 550e8400-e29b-41d4-a716-446655440000), not regular numbers. That's exactly why you hit the ValidationError: "'1' is not a valid UUID." — Django was expecting a UUID but got an integer instead.

Second Issue: Duplicate IDs Breaking Bulk Saves

When you switched to IntegerField, the default=get_next parameter only runs get_next() once when you start creating multiple objects (like in a bulk operation). So every user in your batch ends up with the same ID (e.g., 1). Since primary keys have to be unique, only the first user gets saved, and the rest fail silently (or trigger a database unique constraint error under the hood).


Fix 1: Use Django's Built-in Auto-Increment Key (The Easiest Solution)

Django automatically adds an auto-incrementing integer primary key (id) to every model by default — you don't need to define it manually at all. This handles all the auto-increment logic, including bulk saves, perfectly out of the box.

Your simplified model would look like this:

from django.db import models

class Users(models.Model):
    sex = models.CharField(max_length=100, null=True, default=None)
    age = models.CharField(max_length=100, null=True, default=None)

Now whenever you create users (even in bulk), Django will automatically assign unique, incrementing IDs to each one without any extra code.

Fix 2: Custom Auto-Increment Logic (If You Need It)

If you have specific requirements that force you to handle ID increments manually (like starting from a non-1 value, or custom gaps), you need to fix the "one-time default call" problem and handle concurrent requests to avoid duplicate IDs.

Here's a robust implementation:

from django.db import models, transaction

class Users(models.Model):
    id = models.IntegerField(primary_key=True, editable=False)
    sex = models.CharField(max_length=100, null=True, default=None)
    age = models.CharField(max_length=100, null=True, default=None)

    @classmethod
    def get_next_id(cls):
        # Use an atomic transaction + row lock to prevent race conditions
        with transaction.atomic():
            # Lock the latest user row so no other request can grab the same ID
            latest_user = cls.objects.order_by('-id').select_for_update().first()
            return latest_user.id + 1 if latest_user else 1

    def save(self, *args, **kwargs):
        # Only set the ID if this is a new object
        if not self.id:
            self.id = self.get_next_id()
        super().save(*args, **kwargs)

For Bulk Creation:

Since bulk_create skips calling the save() method on each instance, you'll need to pre-generate unique IDs before inserting:

# Example: Create 5 users in bulk
start_id = Users.get_next_id()
users_batch = [
    Users(id=start_id + i, sex="male", age="25")
    for i in range(5)
]
Users.objects.bulk_create(users_batch)

The select_for_update ensures that even if multiple requests try to create users at the same time, they won't end up with duplicate IDs (the database locks the row until the transaction finishes).

内容的提问来源于stack exchange,提问作者user9341676

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 03:49:05