我有一个合乎逻辑的“如何”或最佳实践问题.
一个简化的例子
我有一个带文本框的模型类.用户可以添加新条目,但只有管理员接受它们才会显示给其他用户.
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添加新的atrribute
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 =无(默认).如果用户修改条目,则从原始条目获取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
最佳答案 会这样的吗?
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(未批准=无))