python – django – 如何在不覆盖原始条目的情况下保存修改后的表单

我有一个合乎逻辑的“如何”或最佳实践问题.

一个简化的例子

我有一个带文本框的模型类.用户可以添加新条目,但只有管理员接受它们才会显示给其他用户.

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(未批准=无))

点赞