我有一个合乎逻辑的"如何"或最佳实践问题。
简化示例
我有一个带文本框的模型类。用户可以添加新条目,但只有管理员接受它们才会显示给其他用户。
class MyClass(models.Model):
# Relation to a user
user = ForeignKey(User)
# Simple textbox as example attribute
text = TextArea()
# Admin has to accept the entry that other users can see it
accepted = BooleanField(default=False)
问题
我想让用户修改一个列表,但管理员必须先接受它们。只要管理员不接受修改,它仍应显示该条目的旧的未修改版本。
我的方法
a)创建一个新类
class MyEditClass(models.Model)
# ForeignKey to the original class
fk = ForeignKey(MyClass)
user = ForeignKey(User)
text = TextArea()
accepted = BooleanField(default=False)
修改将保存在新的表/类中。如果管理员接受此修改后的条目,则原始条目将成为此条目。
为什么我不喜欢它?我的班级有大约60个具有很多关系的属性。由于我还没有找到复制完整类的解决方案,因此产生了大量重复的代码行。如果我添加一个新的attr。在MyClass
我还必须在MyEditClass
...
b)如果条目已被修改,请向MyClass
添加新的属性
class MyClass(models.Model):
# new attribute with the primary key of the edited field
edited_pk = PositiveIntegerField(default=None, blank=True, none=True)
user = ForeignKey(User)
text = TextArea()
accepted = BooleanField(default=False)
在这种情况下,您不会创建新类,而是将已编辑的条目保存在同一个类中,并添加属性edited_pk
。如果条目是新条目集edited_pk = None
(默认值)。如果用户修改条目,则从原始条目获取pk。然后将修改后的一个添加为edited_pk = original_entry.pk
的新条目。如果管理员接受修改后的版本,则原始条目将被修改后的条目覆盖。
为什么我不喜欢这个解决方案?作为管理员,我希望在后端有一个类来接受修改后的条目。
你有其他(可能已经是bultin或第三方)的方法吗?
提前致谢
(标题不好,但我找不到更好的名字。如果你这样做,请编辑)
解决方案
如果您不想使用第三方应用,请检查标记的答案。
我最喜欢的解决方案,也是 Obj3ctiv3_C_88 需要django-simple-history。 因此我创建了一个方法:
class MyClass(models.Model):
user = ForeignKey(User)
text = TextArea()
accepted = BooleanField(default=False)
history = HistoricalRecords() # rtd from django-simple-history
def get_accepted(self):
"""Return the first entry from the history which is accepted."""
return self.history.filter(accepted=True).first()
在您的观点中:
# This code may be optimized, but for now it works
items = MyClass.objects.all()
items = list(items) # convert queryset to a list
i = 0
for item in items:
# Important to get the instance. Otherwise custom methods won't work
items[i] = item.get_accepted().instance
i += 1
答案 0 :(得分:1)
这样的事情会起作用吗?
class BlogComment(models.Model):
blog = models.ForeignKey(Blog)
user = models.ForeignKey(User)
unapproved = models.Charfield(max_length=1000, default=None, Blank=True)
approved = models.Charfield(max_length=1000, default=None, Blank=True)
# on submit
BlogComment.unapproved = request.POST['user_comment']
# on approve
BlogComment.approved = BlogComment.unapproved
BlogComment.unapproved = None
BlogComment.save()
这将允许您为同一评论保留2个不同的状态。您只渲染BlogComment.approved。要查找需要批准的注释,您只需过滤(~Q(未批准=无))