[英]Django non primary_key AutoField
我們正在遷移我們的 Oracle 數據庫並對其進行必要的更改,一個主要的變化是我們將一個UUIDField
作為 primary_key 添加到所有模型(對客戶端隱藏),並且(嘗試添加)一個常規AutoField
。
我們發現直接向我們的客戶顯示 primary_key 不是一個好的設計,但他們也要求顯示一個 ID 字段來更容易地引用對象,但 Django 限制了這一點,不允許AutoField
不是 primary_key
這個問題有解決方法嗎?
我認為可以工作的是使用IntegerField
(幾乎是AutoField
在引擎蓋下使用的),並在模型的第一次保存(在它被放入數據庫之前)增加它。
我寫了一個示例模型來說明這一點。
from django.db import models
class MyModel(models.Model):
# This is what you would increment on save
# Default this to one as a starting point
display_id = models.IntegerField(default=1)
# Rest of your model data
def save(self, *args, **kwargs):
# This means that the model isn't saved to the database yet
if self._state.adding:
# Get the maximum display_id value from the database
last_id = self.objects.all().aggregate(largest=models.Max('display_id'))['largest']
# aggregate can return None! Check it first.
# If it isn't none, just use the last ID specified (which should be the greatest) and add one to it
if last_id is not None:
self.display_id = last_id + 1
super(MyModel, self).save(*args, **kwargs)
理論上,這只是復制AutoField
所做的,只是使用不同的模型字段。
假設在所選的 DBMS 中沒有序列支持,一個解決方案是創建一個模型:
class Counter(models.Model):
count = models.PositiveIntegerField(default=0)
@classmethod
def get_next(cls):
with transaction.atomic():
cls.objects.update(count=models.F('count') + 1)
return cls.objects.values_list('count', flat=True)[0]
並在數據遷移中創建它的一個實例。 如果您使用事務管理,這可能會產生一些影響,但是(如果您的 DBMS 支持事務)保證始終返回下一個數字,無論在事務開始時有多少對象以及是否已刪除任何對象.
您還可以使用計數作為自動增量。 在我的項目中,我是這樣使用的。
def ids():
no = Employee.objects.count()
if no == None:
return 1
else:
return no + 1
emp_id = models.IntegerField(('Code'), default=ids, unique=True, editable=False)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.