考卷列表

博客提及考卷列表,其中第一份是白乌鸦交的。白乌鸦开会时一言不发,却在交考卷一事上表现得积极热情。

第一份是白乌鸦交的:
白乌鸦昨天开会一言不发, 想不到却是最积极,最热情的~!

function showTip(color, x) {
        createTextField("txt", 1, _xmouse+15, _ymouse+20, x.length*5, 16);
        txt.multiline = false;
        txt.wordWrap = true;
        txt.border = true;
        txt.selectable = false;
        txt.borderColor = color;
        myformat = new TextFormat();
        myformat.font = "Verdana";
        myformat.color = color;
        myformat.size = 9;
        txt.text = x;
        onEnterFrame = function () {
                txt._x = _xmouse+15;
                txt._y = _ymouse+20;
                txt.setTextFormat(myformat);
        };
}
function endTip() {
        delete this.onEnterFrame;
        removeMovieClip(txt);
}
//显示tip
btn.onRollOver = function() {
        showTip(0x666666, "This is my first test field object text");
};
btn.onRollOut = endTip;
条理很清晰,简洁, 不错~!
<think>为了在Django Admin的试卷管理下的试卷列表栏增加一个“随机组题”的按钮,我们需要执行以下步骤: 1. 在试卷的Admin中自定义一个操作(action)。 2. 在该操作中,为选中的试卷随机添加一定数量的题目。 3. 考虑到模型结构:一个试卷(Paper)包含多个PaperQuestion(试卷-题目关联),每个PaperQuestion记录了一个题目在试卷中的顺序。 假设我们有一个Paper模型和一个Question模型,并且通过PaperQuestion模型建立多对多关系(带有额外的顺序字段)。 思路: - 在PaperAdmin中定义一个名为`random_select_questions`的自定义操作。 - 操作中,我们需要为每个选中的试卷随机选择若干题目(比如,用户输入一个数量N,然后从题库中随机选择N个题目添加到试卷中)。 - 为了避免重复添加相同的题目,我们需要检查题目是否已经在试卷中。 步骤: 1. 在PaperAdmin的actions列表中添加自定义操作。 2. 在自定义操作函数中,首先获取用户输入的题目数量(可以使用Django的messages框架来获取用户输入,但通常自定义操作不支持直接输入参数。因此,我们可以使用中间视图或者使用Django-admin的另一个方法:通过重写ModelAdmin的get_actions和添加一个表单来获取参数。但这里为了简便,我们可以假设每次随机选择固定数量(比如10题)或者使用一个中间页面让用户输入数量。这里我们采用中间页面的方式,因为需要用户指定数量)。 然而,Django Admin的自定义操作默认不支持在操作执行过程中获取额外参数(除非使用一些技巧)。这里我们使用一个常见的方法:重定向到一个自定义视图来获取参数。 但为了简化,我们先实现一个固定数量(比如10题)的随机组题。然后,再考虑如何让用户输入数量。 这里我们分两个版本: 版本1:固定随机选择10题(不考虑用户输入)。 版本2:通过中间页面让用户输入数量。 由于问题描述中要求的是增加一个操作按钮,我们首先实现版本1,然后给出版本2的思路和部分代码。 ### 版本1:固定数量随机组题 在PaperAdmin中添加一个action,为选中的每个试卷随机添加10个题目(注意:如果试卷中已有题目,则避免重复)。 ```python # 在admin.py中 from django.contrib import admin from .models import Paper, PaperQuestion, Question class PaperAdmin(admin.ModelAdmin): list_display = ['name', ...] # 根据实际模型调整 actions = ['random_select_questions'] def random_select_questions(self, request, queryset): # 固定数量为10 num_questions = 10 for paper in queryset: # 获取该试卷已有的题目ID列表,避免重复 existing_question_ids = PaperQuestion.objects.filter(paper=paper).values_list('question_id', flat=True) # 随机选择题目,排除已经存在的 available_questions = Question.objects.exclude(id__in=existing_question_ids) if available_questions.count() < num_questions: self.message_user(request, f"试卷 {paper.name} 可用的题目不足 {num_questions} 道,只添加了 {available_questions.count()} 道题目。", messages.WARNING) selected_questions = available_questions else: selected_questions = available_questions.order_by('?')[:num_questions] # 随机排序取前num_questions # 创建PaperQuestion记录 for i, question in enumerate(selected_questions, start=1): PaperQuestion.objects.create( paper=paper, question=question, order=i # 顺序从1开始 ) self.message_user(request, f"试卷 {paper.name} 成功添加了 {len(selected_questions)} 道题目。", messages.SUCCESS) random_select_questions.short_description = "随机组题(10道)" admin.site.register(Paper, PaperAdmin) ``` ### 版本2:允许用户输入数量 为了实现用户输入数量,我们需要: 1. 自定义一个中间表单页面,用于输入数量。 2. 在action中,如果选择了多个试卷,我们可以让用户输入一个数量,然后为每个试卷都随机添加这个数量的题目。 步骤: - 在action方法中,如果request的POST方法中有我们自定义的参数(比如'_selected_action'和'action'),则重定向到我们自定义的视图。 - 自定义视图接收用户输入的数量,然后执行随机组题操作。 由于在admin中实现自定义操作带参数相对复杂,这里提供一个简化的方法:使用Django的`action`装饰器,并利用`HttpResponseRedirect`跳转到自定义视图。 由于代码较长,我们简述步骤: 1. 在PaperAdmin中定义action函数,该函数返回一个重定向到自定义视图的响应,并将选中的试卷id传递过去。 2. 自定义一个视图,该视图显示一个表单让用户输入题目数量,然后处理表单,为每个试卷随机添加指定数量的题目。 示例代码: **admin.py** ```python from django.contrib import admin from django.http import HttpResponseRedirect from django.urls import reverse from .models import Paper, PaperQuestion, Question class PaperAdmin(admin.ModelAdmin): list_display = ['name', ...] actions = ['random_select_questions_custom'] def random_select_questions_custom(self, request, queryset): # 将选中的试卷id用逗号分隔,作为参数传递给自定义视图 selected = queryset.values_list('id', flat=True) selected_ids = ','.join(str(id) for id in selected) # 重定向到自定义的视图,该视图会要求输入数量 return HttpResponseRedirect(reverse('random_select_questions') + f'?ids={selected_ids}') random_select_questions_custom.short_description = "随机组题(自定义数量)" admin.site.register(Paper, PaperAdmin) ``` **urls.py** ```python from django.urls import path from . import views urlpatterns = [ # ... 其他路由 path('admin/random_select_questions/', views.random_select_questions_view, name='random_select_questions'), ] ``` **views.py** ```python from django.shortcuts import render, redirect from django.contrib import messages from django.contrib.admin.views.decorators import staff_member_required from .models import Paper, PaperQuestion, Question @staff_member_required def random_select_questions_view(request): if request.method == 'POST': paper_ids = request.POST.get('paper_ids').split(',') num_questions = int(request.POST.get('num_questions')) # 处理每个试卷 for paper_id in paper_ids: try: paper = Paper.objects.get(id=int(paper_id)) existing_question_ids = PaperQuestion.objects.filter(paper=paper).values_list('question_id', flat=True) available_questions = Question.objects.exclude(id__in=existing_question_ids) if available_questions.count() < num_questions: # 如果题目不足,使用所有可用题目 selected_questions = available_questions else: selected_questions = available_questions.order_by('?')[:num_questions] # 添加到试卷,注意顺序 for i, question in enumerate(selected_questions, start=1): PaperQuestion.objects.get_or_create( paper=paper, question=question, defaults={'order': i} # 如果已经存在则不会重复创建 ) messages.success(request, f"试卷 {paper.name} 成功添加了 {len(selected_questions)} 道题目。") except Paper.DoesNotExist: messages.error(request, f"试卷ID {paper_id} 不存在。") return redirect('admin:app_paper_changelist') # 修改为你的试卷changelist的URL name # GET请求,显示表单 paper_ids = request.GET.get('ids', '') return render(request, 'admin/random_select_questions.html', {'paper_ids': paper_ids}) ``` **模板文件:templates/admin/random_select_questions.html** ```html <!DOCTYPE html> <html> <head> <title>随机组题</title> </head> <body> <form method="post"> {% csrf_token %} <input type="hidden" name="paper_ids" value="{{ paper_ids }}"> <label for="num_questions">题目数量:</label> <input type="number" id="num_questions" name="num_questions" min="1" required> <button type="submit">提交</button> </form> </body> </html> ``` ### 解释: - 版本1简单直接,但数量固定。适用于需求固定的场景。 - 版本2通过中间页面让用户输入数量,更加灵活,但实现相对复杂。 - 在版本2中,我们创建了一个自定义视图,只有staff成员可以访问。视图处理GET请求时显示一个简单的表单,POST请求时处理随机组题。 - 注意:在版本2中,我们使用了`PaperQuestion.objects.get_or_create`来避免重复添加同一个题目到同一个试卷(但之前已经排除了,所以这里用create也可以,不过为了保险使用get_or_create)。 ### 注意事项: 1. 随机排序(`order_by('?')`)在数据量大时可能效率低,如果题目数量很多,考虑使用更高效的随机抽样方法(比如使用`random.sample`在Python层面抽样,但注意数据库负载)。 2. 题目添加到试卷时,顺序(`order`字段)我们按添加顺序递增。如果需要真正的随机顺序,可以在创建时随机一个顺序值,但注意顺序不要重复(通常试卷中顺序唯一即可,这里假设顺序从1递增,不重复)。 3. 避免重复添加:在版本1和版本2中,我们都通过排除试卷中已有题目来避免重复。 ### 相关问题: 根据要求,最后提出相关问题。 </think>在 Django Admin 中为试卷管理添加"随机组题"操作按钮,需要创建自定义 Admin Action。以下是完整实现方案和相关解释: ### 解决方案代码 ```python # admin.py from django.contrib import admin, messages from django.db.models import Count from .models import Paper, PaperQuestion, Question class PaperQuestionInline(admin.TabularInline): model = PaperQuestion extra = 0 @admin.register(Paper) class PaperAdmin(admin.ModelAdmin): inlines = [PaperQuestionInline] actions = ['random_add_questions'] # 添加自定义操作 def random_add_questions(self, request, queryset): # 步骤1:获取用户输入的数量 question_count = int(request.POST.get('question_count', 10)) for paper in queryset: # 步骤2:获取试卷已有题目ID existing_ids = paper.questions.values_list('id', flat=True) # 步骤3:随机选择新题目(排除已有题目) new_questions = Question.objects.exclude(id__in=existing_ids).order_by('?')[:question_count] if not new_questions.exists(): self.message_user(request, f"试卷 '{paper.name}' 没有可用的新题目", messages.WARNING) continue # 步骤4:创建试卷-题目关联 last_order = PaperQuestion.objects.filter(paper=paper).aggregate( max_order=Count('order') )['max_order'] or 0 # 步骤5:批量创建关联记录 PaperQuestion.objects.bulk_create([ PaperQuestion( paper=paper, question=question, order=last_order + idx + 1 # 保持顺序递增 ) for idx, question in enumerate(new_questions) ]) self.message_user(request, f"试卷 '{paper.name}' 成功添加 {len(new_questions)} 道随机题目", messages.SUCCESS) random_add_questions.short_description = "随机组题" # 可选:添加数量选择表单 def get_form(self, request, obj=None, **kwargs): form = super().get_form(request, obj, **kwargs) if 'actions' in request.POST and request.POST['action'] == 'random_add_questions': form.base_fields['question_count'] = forms.IntegerField( label='题目数量', min_value=1, initial=10, help_text='选择要随机添加的题目数量' ) return form ``` ### 代码功能解释 1. **Admin Action 注册**: - `actions = ['random_add_questions']` 将自定义操作添加到试卷管理界面 - `short_description` 设置操作按钮的显示文本 2. **随机选题逻辑**: - `order_by('?')` 使用数据库随机排序功能 - `exclude(id__in=existing_ids)` 排除试卷中已存在的题目 - `question_count` 参数控制添加题目数量(默认为10) 3. **关联记录创建**: - `bulk_create()` 高效批量创建关联记录 - `order` 字段自动计算,确保题目顺序连续递增 - 使用聚合函数(`aggregate`)获取当前最大序号 4. **用户反馈**: - `message_user()` 显示操作结果通知 - 处理无可用题目时的警告场景 ### 使用说明 1. 在试卷列表页选中一个或多个试卷 2. 从操作下拉菜单中选择"随机组题" 3. 系统会自动为每个试卷添加指定数量的随机题目 4. 结果将在顶部显示操作通知 ### 优化建议 1. **添加数量选择表单**: 取消代码中`get_form`方法的注释,可在操作时弹出题目数量输入框 2. **题目型过滤**: 如需按题型筛选,可修改查询逻辑: ```python # 只选择选择题 new_questions = Question.objects.filter(type='choice').exclude(id__in=existing_ids).order_by('?')[:question_count] ``` 3. **性能优化**: - 对于大题量题库,使用`random.sample()`代替`order_by('?')` - 添加`select_related`优化查询效率
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值