如何在Django中根据编辑信息的内容扣除用户积分?

问一个 django 编辑信息扣除相应用户积分的问题

class EditTopicForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        self.topic_id = kwargs.pop('topic_id', None)
        #以上两条语句取不到相应的值
        super(EditTopicForm, self).__init__(*args, **kwargs)
        
    class Meta:
        model = Topic
        #fields = "__all__"
        fields = ['title', 'body', 'ys_t','is_cuti']

    def save(self, commit=True):
        inst = super(EditTopicForm, self).save()        
        if inst.is_cuti:
            inst.author.levels -= 2
            inst.author.save(update_fields = ['levels'])
        if inst.ys_t:
            inst.author.levels -= 2
            inst.author.save(update_fields = ['levels'])
        return inst

本意是用户发布信息后,编辑信息时如果给标题“加粗”,变“颜色”时就会扣除用户积分 2,如果不做此操作的话就不扣除积分

问题是如果用户本身就已经“加粗”或变颜色了。那再编辑信息只改其它如标题或内容时,这样的情况就不再扣积分了。

如上面代码只要编辑信息就会扣除相应的积分。

我现在想到的办法:

  1. 把加粗或变色单独写一个操作函数。
  2. 在 models 或 forms 里 在修改信息时 直接在 def save() 里实现。就是先取到修改前信息的 is_cutiys_t 字段的值跟修改后的值做比较后再决定是否执行扣积分问题

现在不知道怎么先取到修改前的值? 如上面所示代码都是取到的修改后的值。

在构造函数里 __init__ 里取不到东西。也可能我写的代码不对

不知道哪位朋友有什么方法能实现这个功能吗?
多谢了

阅读 1.1k
avatarAI BotBETA

要在Django中实现根据编辑信息的内容扣除用户积分的功能,并且只在信息的内容有所改变(比如标题加粗或变色)时才扣除积分,你可以通过比较编辑前后的模型字段值来决定是否扣分。

首先,你需要获取到编辑前的Topic实例的is_cutiys_t字段的值。这通常意味着在编辑操作之前,你需要先从数据库中检索出原始的Topic对象。

这里有一个简单的实现方法:

  1. 在视图中,先从数据库中获取原始的Topic对象。
  2. 使用这个原始对象创建一个表单实例,并且绑定请求的数据。
  3. 在表单的save方法中,比较原始对象和即将保存的对象之间的is_cutiys_t字段的值。
  4. 如果字段值发生了变化,则执行扣除积分的操作。

以下是一个简化的示例代码:

视图(views.py):

from django.shortcuts import get_object_or_404, render
from .models import Topic
from .forms import EditTopicForm

def edit_topic(request, topic_id):
    topic = get_object_or_404(Topic, pk=topic_id)
    if request.method == 'POST':
        form = EditTopicForm(request.POST, instance=topic, user=request.user)
        if form.is_valid():
            original_is_cuti = topic.is_cuti
            original_ys_t = topic.ys_t
            topic = form.save()
            
            # 比较原始值和保存后的值
            if topic.is_cuti != original_is_cuti or topic.ys_t != original_ys_t:
                # 如果值改变了,则扣除积分
                request.user.levels -= 2  # 假设用户模型有levels字段表示积分
                request.user.save(update_fields=['levels'])
            
            # 重定向或返回成功消息
            return redirect('topic_detail', topic_id=topic.id)
    else:
        form = EditTopicForm(instance=topic, user=request.user)
    
    # 渲染表单
    return render(request, 'edit_topic.html', {'form': form})

表单(forms.py):

from django import forms
from .models import Topic

class EditTopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        fields = ['title', 'body', 'is_cuti', 'ys_t']

    def __init__(self, *args, **kwargs):
        self.user = kwargs.pop('user', None)
        super(EditTopicForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        # 在这里,你不需要检查is_cuti或ys_t字段,因为比较逻辑已经在视图中处理了
        return super(EditTopicForm, self).save(commit=commit)

请注意,这个示例假设Topic模型有一个author字段,它关联到用户(User)模型,并且用户模型有一个levels字段来表示积分。你需要根据你的实际模型结构来调整这些字段名。

在上面的代码中,我们首先通过get_object_or_404获取到原始的Topic对象。然后,我们使用这个对象来创建表单实例,并绑定请求的数据。在表单验证通过后,我们比较原始Topic对象的is_cutiys_t字段与即将保存的对象中的相应字段。如果检测到变化,则扣除用户积分。

请根据你的具体需求调整上述代码,并确保你的模型结构和字段名称与代码中的假设相匹配。

1 个回答

可以简单理解为,怎么将这个操作做成一个幂等操作

用户对内容(cid)可以随便编辑,当触发某个操作(op)时,扣减积分。是否清除之后,会恢复积分?

cid + op 作为一个唯一值,每次扣减时,判断下是否存在(已扣减过),没有则扣减并新增一条扣减记录。当然这属于一个事务。

同时,还可以将这个数据冗余至 内容 中,比如xx_is_cutixx_ys_t 当这个内容发生过扣减就置为1。每次扣减时判断是否为1?


也就是 将扣减状态持久化下来,并与具体内容做关联。不容易出错,同时也比较好回溯

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进