我有一个简单的通知模型:
class Notification(models.Model):
user = models.ForeignKey(User)
sender = models.ForeignKey(User)
model = '''What to put here?'''
comment = models.CharField(max_length=200)
created = models.DateTimeField(auto_now=False,auto_now_add=True)
我需要通知与几个不同的模型相关,例如;帖子,用户跟随等
在django中你是否可以与几个模型相关而不是为每个模型创建一个通知模型?
我想避免这样的模型: PostLikeNotification,UserFollowNotification等
django也有这个功能吗?我无法在文档中找到它。
答案 0 :(得分:1)
您可以使用Content Types / Generic Relations
error: 'const class __gnu_cxx::__normal_iterator<const MyClassA<double>*, std::vector<MyClassA<double> > >' has no member named 'valA'
这里我们存储Notification模型中相关对象的模型(Using the Content Types framework)和主键(在本例中必须是整数),然后添加一个属性方法来获取相关对象。
通过此功能,您可以将通知与任何其他模型相关联。您还可以使用class Notification(models.Model):
user = models.ForeignKey(User)
sender = models.ForeignKey(User)
object_id = models.PositiveIntegerField(default=None, null=True)
content_type = models.ForeignKey(ContentType, default=None, null=True)
comment = models.CharField(max_length=200)
created = models.DateTimeField(auto_now=False,auto_now_add=True)
@property
def model_object(self):
content_type = self.content_type
object_id = self.object_id
if content_type is not None and object_id is not None:
MyClass = content_type.model_class()
model_object = MyClass.objects.filter(pk=object_id)
if model_object.exists():
return model_object.first()
return None
字段上的ForeignKey.limit_choices_to
参数来验证它是否只接受某些模型。
答案 1 :(得分:0)
Django需要在创建关系之前知道模型,您可以将模型存储在char字段中,如// Returns whether 'root' is a balanced tree.
// Also stores the tree's height in *height.
bool balanced_height(node* root, int* height)
{
// The trivial base case – an empty tree is balanced and has height 0.
if (root == nullptr)
{
*height = 0;
return true;
}
// Information gathering using recursion:
// Find out whether the subtrees are balanced, and get their heights.
int leftheight = 0;
int rightheight = 0;
bool leftbalance = balanced_height(root->left, &leftheight);
bool rightbalance = balanced_height(root->right, &rightheight);
// Now that we know the heights of the subtrees, we can store the height of this tree.
*height = max(leftheight, rightheight) + 1;
// Finally, a translation into C++ of the definition:
// A tree is balanced if and only if
// - the subtrees are balanced, and
// - the heights of the subtrees differ by at most one.
return leftbalance && rightbalance && abs(leftheight - rightheight) <= 1;
}
bool balanced(node* root)
{
int height = 0;
return balanced_height(root, &height);
}
post:23
,并定义一个user_follow:41
方法,该方法将解析该字段并返回正确的模型对象
答案 2 :(得分:0)
一切都取决于您的设计,您有几种选择。不同的选项取决于数据库的大小:
使用抽象模型并实际创建PostLikeNotification
和UserFollowNotification
以及此类其他模型。
class Notification(models.Model):
# ...
class Meta:
abstract = True
class PostLikeNotification(Notification):
model = models.ForeignKey(SomePost)
class UserFollowNotification(Notifcation):
model = models.ForeignKey(Follower)
# ...
这有几个好处:
当然,这有一些缺点:
您可以使用简单的django
并在其中存储模型名称和ID。或两个字段一个用于名称,另一个用于id。
CharField
优点:
class Notification(models.Model):
model_type = models.CharField(max_len=48)
model_id = models.PositiveInteger()
以获得额外的速度)。缺点:
这只是在以下两个选项之间实现中间地带的方式:添加几个可以为空的外键。其他实现中间立场的方式也存在。
model_type
优势:
缺点:
如果您刚刚开始一个项目,并且您不知道(或者不担心)数据量,那么会创建多个表。为此目的创建了抽象模型。
另一方面,如果您要阅读和过滤大量通知(很多,我的意思是数百万),那么您有充分的理由创建单个通知表并在更高级别处理关系。请注意,这会导致锁定问题,如果您有一个表,则(几乎)永远不会锁定通知。