Python中如何在Django中实现点击按钮查看资源并扣积分,并让用户与资源关联

比如

资源信息
class NiHao(models.Model):
mingzi = models.CharField(max_length=60, verbose_name=(u’名字 /称呼’), blank = True, null = True,)
vip = models.CharField(max_length=60, verbose_name=
(u’看这里要扣积分’), blank = True, null = True,)
body = models.TextField(_(u’求职主要介绍,教育经历,工作经历等’))
mmtags = models.ManyToManyField(‘MmTags’, verbose_name = _(u’标签信息’), blank = True)
category = models.ForeignKey(‘Category’, verbose_name = (‘栏目分类’))
level = models.IntegerField(default=2, verbose_name=u’值几分’)

用户信息
class User(AbstractUser):
levels = models.IntegerField(default=0, verbose_name = u’总积分’)
nickname = models.CharField(max_length=36, blank=True, null=True, verbose_name=u’名称’)
list_id = models.PositiveIntegerField(
(u’信息类型区别’), default = 0)

如果一个用户要看资源里的 VIP 字段的信息 需要点击一个按妞,ajax 需要一个涵数执行 aauser.levels - bbnihao.level 这样

如果用户这次查看了。下次再看还需要再扣积分。不知道用 django 实现的话。怎么样让用户与这个资源有一个标志。
当用户再查看到这信息的时候。不需要再扣积分

不知这样说能让大家明白我要解决的问题不。
水行有限实在没想出啥思种。哪位大神指导一下?
Python中如何在Django中实现点击按钮查看资源并扣积分,并让用户与资源关联


7 回复

难道没使用数据库吗


我来给你一个完整的实现方案。这个需求的核心是建立用户、积分和资源的三方关联,并在访问时进行积分扣除。

首先,你需要建立数据模型:

# models.py
from django.db import models
from django.contrib.auth.models import User

class Resource(models.Model):
    title = models.CharField(max_length=200)
    description = models.TextField()
    file = models.FileField(upload_to='resources/')
    points_required = models.IntegerField(default=0)  # 查看所需积分
    created_at = models.DateTimeField(auto_now_add=True)

class UserProfile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    points = models.IntegerField(default=0)  # 用户当前积分

class ResourceAccess(models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    resource = models.ForeignKey(Resource, on_delete=models.CASCADE)
    accessed_at = models.DateTimeField(auto_now_add=True)
    points_deducted = models.IntegerField()  # 本次扣除的积分
    
    class Meta:
        unique_together = ['user', 'resource']  # 防止重复下载

然后是视图逻辑:

# views.py
from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required
from django.http import HttpResponse, JsonResponse
from django.views.decorators.csrf import csrf_exempt
from .models import Resource, UserProfile, ResourceAccess

@login_required
def view_resource(request, resource_id):
    resource = get_object_or_404(Resource, id=resource_id)
    user_profile = UserProfile.objects.get_or_create(user=request.user)[0]
    
    # 检查积分是否足够
    if user_profile.points < resource.points_required:
        return JsonResponse({
            'success': False,
            'message': '积分不足'
        })
    
    # 检查是否已经访问过
    if ResourceAccess.objects.filter(user=request.user, resource=resource).exists():
        # 已经访问过,直接返回资源
        return serve_resource(resource)
    
    # 扣除积分并记录访问
    user_profile.points -= resource.points_required
    user_profile.save()
    
    # 创建访问记录
    ResourceAccess.objects.create(
        user=request.user,
        resource=resource,
        points_deducted=resource.points_required
    )
    
    return serve_resource(resource)

def serve_resource(resource):
    # 根据你的需求返回文件或重定向
    response = HttpResponse(resource.file, content_type='application/octet-stream')
    response['Content-Disposition'] = f'attachment; filename="{resource.file.name}"'
    return response

前端按钮点击的AJAX调用:

<!-- template.html -->
<button onclick="viewResource({{ resource.id }})" 
        class="btn btn-primary">
    查看资源 (需要 {{ resource.points_required }} 积分)
</button>

<script>
function viewResource(resourceId) {
    fetch(`/resources/${resourceId}/view/`, {
        method: 'GET',
        headers: {
            'X-CSRFToken': '{{ csrf_token }}',
        }
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // 如果后端直接返回文件,这里需要处理文件下载
            window.location.href = `/resources/${resourceId}/download/`;
        } else {
            alert(data.message);
        }
    });
}
</script>

URL配置:

# urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('resources/<int:resource_id>/view/', views.view_resource, name='view_resource'),
]

这个方案的关键点:

  1. 使用中间表ResourceAccess记录用户和资源的关联
  2. 在访问时实时检查积分并扣除
  3. 使用唯一约束防止重复扣除积分
  4. 完整的积分扣除和访问记录

总结:用中间表关联用户和资源,访问时检查并扣除积分。

总该有个统计信息的“库”吧
不管是文件还是数据库,加一个字段标识,扣积分的时候修改值
下次用户登录的时候就加载到 session 里面,这是最简单的


肯定用。我现在想到了一个思路正在试。不知道可以不

建个库存放用户 id 和资源 id 的关系,

用 Contenttypes ?

这个是很简单的问题啊,直接再弄一个 Model
通常只要两个字段,user_id, resource_id, 分别外键到 User Model 和 Nihao Model
这么弄最省事,逻辑上也简单,但是只能用于数据量不大的情况。

这么弄如果在用户量比较大,资源量也很大的情况下要考虑一下性能问题。
那样话只能用 redis 这种内存数据库,把 user_id 做键对应列表,所有访问过的资源 id 压到 list 里面。
不过要考虑一下数据持久化方案。

回到顶部