python - 根据外键设置唯一主键
问题描述
我有一个模型定义为 -
class sales_order(models.Model):
customer=models.ForeignKey()
item=models.ForeignKey()
branch=models.ForeignKey()
---
---other fields
现在对于每个分支,我想从 1 开始主键(例如“id”),但 Django 的默认功能将增加 id 而与任何其他数据无关。
即使 id 继续递增,我也可以,然后我设置自己的字段,使其每个分支都是唯一的,并且该字段应自动递增,而无需用户通过检查数据库中的前一个值来传递数据,例如 -
class order_serializer(serializers.ModelSerializer):
class Meta:
validators = [
UniqueTogetherValidator(
queryset=sales_order.objects.all(),
fields=['myOwnDefinedField', 'branch']
)
]
我不知道如何实现这一目标。使用 Django 3.1.5。
有什么帮助吗?
解决方案
在模型的save
方法中,您可以执行查询以获取当前分支字段中的最大值,将此值加 1,然后将其保存为新值。只有在还没有值的情况下才这样做,这样我们就不会覆盖现有的行
也使用Meta.unique_together在数据库级别强制执行此约束
from django.db.models.functions import Coalesce
class SalesOrder(models.Model):
branch = models.ForeignKey(Branch, on_delete=models.CASCADE)
branch_unique_id = models.IntegerField(editable=False, blank=True)
class Meta:
unique_together = (
('branch', 'branch_unique_id'),
)
def save(self, *args, **kwargs):
if not self.branch_unique_id:
self.branch_unique_id = SalesOrder.objects.filter(
branch=self.branch
).aggregate(
max=Coalesce(models.Max('branch_unique_id'), 0)
)['max'] + 1
super().save(*args, **kwargs)
推荐阅读
- material-table - 材料表中的错误消息
- vue.js - Vue 时刻删除空间
- html - 如何使网站图标显示在网页中?
- python - 在python中的变量中捕获输出
- c++ - 迭代任一向量时如何避免代码重复
还是数字范围? - python - 在python中创建数据框中所有可能的行组合
- rust - 特征 `std::borrow::Borrow
` 没有为 `&str` 实现 - xaml - 按钮内的 Xamarin.Forms TextBlock。文本的自定义换行
- julia - 如何在 Julia 中将参数显式键入为函数
- flutter - 如何在 Flutter 中为圆圈设置动画(如 gif 所示)?