如何使用外键(另一个模型)上的字段作为我的模型主键值的一部分
How to use a field on a foreign key (another model) as part of my model primary key value
我是 Django 的新手,我觉得有时我不清楚应该在 myApp 的哪个 .py 中编写我看到的解决方案和示例。
在我的 models.py 中,我有一个名为 Project 的模型和一个名为 Order 的模型。在管理部分 (http://127.0.0.1:8000/admin/myApp/),我希望用户在创建新项目时输入项目编号。每个项目都可以有多个订单。我希望订单主键由它所属的项目编号加上一个连续的数字组成。用户只能修改Oder主键的连续号部分,不能修改订单所属的Project号。
例如对于 project_number(主键)= 951 的项目,订单主键可以是 951-1、951-2 等
project_number(主键) = 1015 的另一个项目也可以有订单 1,2 等,但它们不会与项目 951 的订单冲突,因为它们将被标记为 1015-1、1015- 2等
- 是否可以在 models.py 中实现?
- 我将如何修改下面的 order_number 字段?
注意我需要 order_number 字段从 order_project 字段获取它的 project_number 并且在用户创建之前我不知道 order_project 的确切值订单并将其与项目相关联。
如果无法完成我所要求的,请提出解决此问题的方法,并清楚说明我应该在 myApp 的哪个 .py 中编写代码。
class Project(models.Model):
project_number = models.IntegerField(unique=True,primary_key=True)
project_name = models.CharField(max_length=400)
class Order(models.Model):
order_project = models.ForeignKey("Project", on_delete=models.CASCADE,verbose_name = "Project to which this order is associated",related_name= "orders_for_project")
order_number = models.CharField(unique=True,primary_key=True,max_length = 10)
更新:
根据社区的建议,我的代码现在如下所示:
class Project(models.Model):
project_number = models.IntegerField(unique=True,primary_key=True)
project_name = models.CharField(max_length=400)
class Order(models.Model):
order_project = models.ForeignKey("Project", on_delete=models.CASCADE,verbose_name = "Project to which this order is associated",related_name= "orders_for_project")
order_number = models.IntegerField(default=1,validators=[MinValueValidator(1)])
class Meta:
#TODO capture error and present it in human readable form
constraints = [ models.UniqueConstraint(fields= ['order_project','order_number'], name = 'unique_order_id'),]
def __str__(self):
return str(self.order_project.project_number) + ("-") + str(self.order_number) + (" : ") + str(self.order_description)
考虑到 Project 的主键值,我不完全理解为什么我的 Order 主键无法形成,但这是一个变通解决方案
可以让Order的主键独立于Product的PK,只需要对order_project_id
+ order_number
组合设置唯一性约束:
class Order(models.Model):
order_project = models.ForeignKey("Project", on_delete=models.CASCADE,verbose_name = "Project to which this order is associated",related_name= "orders_for_project")
order_number = models.IntegerField()
class Meta:
unique_together = ('order_project', 'order_number')
然后,如果您想以 {order_project_id}-{order_number}
格式显示订单号,您可以在运行时使用这两个字段生成此值。
我是 Django 的新手,我觉得有时我不清楚应该在 myApp 的哪个 .py 中编写我看到的解决方案和示例。
在我的 models.py 中,我有一个名为 Project 的模型和一个名为 Order 的模型。在管理部分 (http://127.0.0.1:8000/admin/myApp/),我希望用户在创建新项目时输入项目编号。每个项目都可以有多个订单。我希望订单主键由它所属的项目编号加上一个连续的数字组成。用户只能修改Oder主键的连续号部分,不能修改订单所属的Project号。
例如对于 project_number(主键)= 951 的项目,订单主键可以是 951-1、951-2 等
project_number(主键) = 1015 的另一个项目也可以有订单 1,2 等,但它们不会与项目 951 的订单冲突,因为它们将被标记为 1015-1、1015- 2等
- 是否可以在 models.py 中实现?
- 我将如何修改下面的 order_number 字段?
注意我需要 order_number 字段从 order_project 字段获取它的 project_number 并且在用户创建之前我不知道 order_project 的确切值订单并将其与项目相关联。
如果无法完成我所要求的,请提出解决此问题的方法,并清楚说明我应该在 myApp 的哪个 .py 中编写代码。
class Project(models.Model):
project_number = models.IntegerField(unique=True,primary_key=True)
project_name = models.CharField(max_length=400)
class Order(models.Model):
order_project = models.ForeignKey("Project", on_delete=models.CASCADE,verbose_name = "Project to which this order is associated",related_name= "orders_for_project")
order_number = models.CharField(unique=True,primary_key=True,max_length = 10)
更新:
根据社区的建议,我的代码现在如下所示:
class Project(models.Model):
project_number = models.IntegerField(unique=True,primary_key=True)
project_name = models.CharField(max_length=400)
class Order(models.Model):
order_project = models.ForeignKey("Project", on_delete=models.CASCADE,verbose_name = "Project to which this order is associated",related_name= "orders_for_project")
order_number = models.IntegerField(default=1,validators=[MinValueValidator(1)])
class Meta:
#TODO capture error and present it in human readable form
constraints = [ models.UniqueConstraint(fields= ['order_project','order_number'], name = 'unique_order_id'),]
def __str__(self):
return str(self.order_project.project_number) + ("-") + str(self.order_number) + (" : ") + str(self.order_description)
考虑到 Project 的主键值,我不完全理解为什么我的 Order 主键无法形成,但这是一个变通解决方案
可以让Order的主键独立于Product的PK,只需要对order_project_id
+ order_number
组合设置唯一性约束:
class Order(models.Model):
order_project = models.ForeignKey("Project", on_delete=models.CASCADE,verbose_name = "Project to which this order is associated",related_name= "orders_for_project")
order_number = models.IntegerField()
class Meta:
unique_together = ('order_project', 'order_number')
然后,如果您想以 {order_project_id}-{order_number}
格式显示订单号,您可以在运行时使用这两个字段生成此值。