Django:如何创建一个由给定外键分组(排名)的辅助ID字段?

发布于 2025-02-12 23:30:11 字数 1889 浏览 2 评论 0 原文

输出可能看起来像这样,例如:

ID Secondary_id FK
1 1 1 1
2 2 1
3 3 1
4 1 2
5 2 2

在上下文中:(

请参见下面的模型)

我有一个佣金结构,该结构将取决于多少用户一个月内收入。 理想情况下,我需要在我的佣金支架模型中知道,这是给定结构的支架索引。

这是我的模型。

class CommissionStructure(APIBaseModel):
    advisor = models.ManyToManyField(AdviserDetail)
    name = models.CharField(max_length=20, blank=True, null=True, default='default')
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    start_dt = models.DateTimeField(auto_now_add=True)
    end_dt = models.DateTimeField(default=timezone.datetime.max)

    objects = CommissionStructureManager()



class CommissionBracket(APIBaseModel):
    <secondary_id ???>
    commission_structure = models.ForeignKey(CommissionStructure, on_delete=models.CASCADE, related_name="brackets")
    lower_bound = models.DecimalField(decimal_places=2, default=0.00, max_digits=20, null=True, blank=True)
    upper_bound = models.DecimalField(decimal_places=2, default=0.00, max_digits=20, null=True, blank=True)

请注意,如果可以在聚合套件中添加注释,我可能不必将其存储在模型上,但我的偏爱是擦干。

谢谢

The output could look like this, for example:

id secondary_id fk
1 1 1
2 2 1
3 3 1
4 1 2
5 2 2

For context:

(see models below)

I have a commission structure which will have brackets depending on how much a user is earning in a month.
Ideally, I need to know in my Commission Bracket model, the bracket index for a given structure.

Here are my models.

class CommissionStructure(APIBaseModel):
    advisor = models.ManyToManyField(AdviserDetail)
    name = models.CharField(max_length=20, blank=True, null=True, default='default')
    company = models.ForeignKey(Company, on_delete=models.CASCADE)
    start_dt = models.DateTimeField(auto_now_add=True)
    end_dt = models.DateTimeField(default=timezone.datetime.max)

    objects = CommissionStructureManager()



class CommissionBracket(APIBaseModel):
    <secondary_id ???>
    commission_structure = models.ForeignKey(CommissionStructure, on_delete=models.CASCADE, related_name="brackets")
    lower_bound = models.DecimalField(decimal_places=2, default=0.00, max_digits=20, null=True, blank=True)
    upper_bound = models.DecimalField(decimal_places=2, default=0.00, max_digits=20, null=True, blank=True)

Please note, I may not have to store it on my model if I can add an annotation to an aggregate set, but my preference is to follow DRY.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

何处潇湘 2025-02-19 23:30:11

我的建议是。您可以将辅助ID添加为 commissionBracket 中的整数字段。然后,您可以实现以下内容:

from django.db import connection

def sample_view(request):
   ...

   with connection.cursor() as cursor:
      cursor.execute('''
         INSERT INTO appname_commissionbracket (
            secondary_id, 
            commission_structure_id
         )
         SELECT CASE 
            WHEN MAX(secondary_id)
               THEN MAX(secondary_id) + 1
               ELSE 1
            END AS new_secid, %s
         FROM appname_commissionbracket 
         WHERE commission_structure_id = %s''',
         [1, 1] # Sample foreign key value
      )

   return render(...)

在这里我们使用 ins select 从同一表中基于新记录的 secondary_id 。我们还添加a case ,以便我们可以在没有记录的情况下拥有后退值使用 commission_structure_id 值返回1。

如果您需要在创建过程中填充其他列,则可以简单地将它们包括在内:

INSERT INTO (secondary_id, commission_structure_id, lower_bound, upper_bound)
SELECT CASE ... END AS new_secid, <fk_value>, <lower_bound_value>, <upper_bound_value>

My suggestion would be to execute custom SQL directly. You can add the secondary id as an integer field in CommissionBracket. Then, you can implement this:

from django.db import connection

def sample_view(request):
   ...

   with connection.cursor() as cursor:
      cursor.execute('''
         INSERT INTO appname_commissionbracket (
            secondary_id, 
            commission_structure_id
         )
         SELECT CASE 
            WHEN MAX(secondary_id)
               THEN MAX(secondary_id) + 1
               ELSE 1
            END AS new_secid, %s
         FROM appname_commissionbracket 
         WHERE commission_structure_id = %s''',
         [1, 1] # Sample foreign key value
      )

   return render(...)

Here we're using INSERT INTO SELECT since we're basing the new record's secondary_id from the same table. We're also adding a CASE so that we can have a fallback value if no record with commission_structure_id value as 1 is returned.

In case you need to populate other columns during create, you can simply include them like so:

INSERT INTO (secondary_id, commission_structure_id, lower_bound, upper_bound)
SELECT CASE ... END AS new_secid, <fk_value>, <lower_bound_value>, <upper_bound_value>
雄赳赳气昂昂 2025-02-19 23:30:11

我找到了一种注释QuerySet的方法,但是为了兴趣,我最初的问题仍然存在:如何添加外键分区的另一个字段?

brackets = CommissionBracket.objects.select_related("commission_structure")\
            .prefetch_related(
            'commission_structure__advisor',
            'commission_structure__start_dt__gte',
            'commission_structure__end_dt__lte',
            'commission_structure__company',
            'bracket_values'
            ).filter(
                commission_structure__advisor=advisor,
                commission_structure__start_dt__lte=date,
                commission_structure__end_dt__gte=date,
                commission_structure__company=advisor.user.company,
            ).annotate(index=Window(
                    expression=Count('id'),
                    partition_by="commission_structure",
                    order_by=F("lower_bound").asc()))

I've found a way to annotate the queryset, but for interest, my original question still remains: how do I add another field partitioned by the foreign key?

brackets = CommissionBracket.objects.select_related("commission_structure")\
            .prefetch_related(
            'commission_structure__advisor',
            'commission_structure__start_dt__gte',
            'commission_structure__end_dt__lte',
            'commission_structure__company',
            'bracket_values'
            ).filter(
                commission_structure__advisor=advisor,
                commission_structure__start_dt__lte=date,
                commission_structure__end_dt__gte=date,
                commission_structure__company=advisor.user.company,
            ).annotate(index=Window(
                    expression=Count('id'),
                    partition_by="commission_structure",
                    order_by=F("lower_bound").asc()))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文