gpt4 book ai didi

python - 使用 GenericForeignKey 进行 Django 模型设计

转载 作者:行者123 更新时间:2023-11-30 23:29:51 30 4
gpt4 key购买 nike

我有一个计划模型,只能分配 2 个奖励,一个奖励给该计划的成员,另一个奖励给他们的 friend 。

下面是我如何为此设计模型,但现在我开始质疑设计,方案和奖励的链接是否不正确?我应该在抽象奖励上建立相反的关系吗?

方案:

class Scheme(models.Model):
name = models.CharField(max_length=60)

participant_reward_content_type = models.ForeignKey(ContentType,
editable=False,
related_name='%(app_label)s_%(class)s_as_participant',
null=True, blank=True
)
participant_reward_object_id = models.PositiveIntegerField(null=True, blank=True)
participant_reward = generic.GenericForeignKey('participant_reward_content_type', 'participant_reward_object_id')

friend_reward_content_type = models.ForeignKey(ContentType,
editable=False,
related_name='%(app_label)s_%(class)s_as_friends',
null=True, blank=True
)
friend_reward_object_id = models.PositiveIntegerField(null=True, blank=True)
friend_reward = generic.GenericForeignKey('friend_reward_content_type', 'friend_reward_object_id')

奖励:

class AbstractReward(models.Model):
"""
Abstract reward common information shared for all rewards.
"""
description = models.CharField(max_length="150")
active = models.BooleanField(default=True)
#scheme = models.ForeignKey(Scheme, null=True,)

class Meta:
abstract = True


class SingleVoucherReward(AbstractReward):
"""
Single-use coupons are coupon codes that can only be used once
"""
pass

class Meta:
app_label = 'schemes'


class MultiVoucherReward(AbstractReward):
"""
A multi-use coupon code is a coupon code that can be used unlimited times.
"""
code = models.CharField(max_length=200)
expiry = models.DateTimeField(null=True)

class Meta:
app_label = 'schemes'


class CustomReward(AbstractReward):
"""
A reward class used when it can't be handled or they would like to
handle reward fulfillment themselves.
"""
pass

class Meta:
app_label = 'schemes'

最佳答案

我建议保持简单 - http://en.wikipedia.org/wiki/KISS_principle

鉴于 3 种奖励类型的数据定义相似,我将完全失去继承,而只给它一个类型选择:

class Reward(models.Model):
SINGLE = 'Single'
MULTI = 'Multi'
CUSTOM = 'Custom'
TYPE_CHOICES = (
(SINGLE, 'Single'),
(MULTI, 'Multi'),
(CUSTOM, 'Custom'),
)

description = models.CharField(max_length="150")
active = models.BooleanField(default=True)

type = models.CharField(max_length=10, choices=TYPE_CHOICES, default=SINGLE)

code = models.CharField(max_length=200, blank=True)
expiry = models.DateTimeField(null=True)

Two Scoops of Django - 这是关于如何在 Django 中处理事务的一个很好的引用 - 也推荐这种方法。

这也意味着您不需要 GenericForeignKey 并且可以使用简单的外键,从而再次大幅降低复杂性:

class Scheme(models.Model):
name = models.CharField(max_length=60)

participant_reward = models.ForeignKey('Reward', null=True, blank=True)
friend_reward = models.ForeignKey('Rewards', null=True, blank=True)

内置的 Django 管理和 ModelForms 之类的东西将通过这种方法开箱即用。

有些人可能不喜欢 TYPE_CHOICES 的冗长。但维护起来却如此简单明了。

我还意识到,您最终可能会得到 Reward 类上的方法,这些方法必须修改不同类型的行为,例如:

if self.type = CUSTOM:
pass

但这又非常容易维护。您可以使用 Proxy Models如果代码开始真正出现分歧。

有些人可能会说这不是“Pythonic”,但我们在这里不处理纯Python类,除了Zen of Python之外。第三条原则是:

Simple is better than complex.

关于python - 使用 GenericForeignKey 进行 Django 模型设计,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20940574/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com