Django ModelForm如何设置数据库中用户最新选项为默认值?
问题分析与解决方案
首先,你在模型里设置default=Eintrag.objects.filter(Name=request.user).Anmeldung的做法是完全不可行的——模型定义时根本无法获取request对象(request是视图层面的上下文,模型初始化时不存在),而且语法上也有错误(filter返回的是查询集,不能直接访问.Anmeldung)。
正确的做法是不在模型层面处理用户个性化的默认值,而是在视图或表单中根据当前用户的已有数据来初始化表单。下面是具体的修复步骤:
1. 先修复模型中的错误
把Anmeldung字段的default参数修改为一个静态值(比如默认选择"Noch nicht entschieden"),或者直接去掉(如果不需要全局默认):
# models.py from django.db import models Anmeldung = ( ('1', 'Ja'), ('2', 'Nein'), ('3', 'Noch nicht entschieden'), ) Essen = ( ('1', 'Fleisch'), ('2', 'Fisch'), ('3', 'Vegetarisch'), ) class Eintrag(models.Model): Name = models.CharField(max_length=200) # 建议改成关联User模型的外键:models.ForeignKey(User, on_delete=models.CASCADE),比存用户名更规范 Anmeldung = models.CharField( max_length=2, choices=Anmeldung, default='3' # 设置全局默认,或者去掉这个参数 ) Essen = models.CharField( max_length=2, choices=Essen, default='1' ) pub_date = models.DateTimeField('date published')
额外建议:把
Name字段改成关联User模型的外键,这样能避免用户名重复的问题,也更符合Django的用户关联规范。
2. 修改视图逻辑,用用户已有数据初始化表单
在GET请求时,先查询当前用户的Eintrag记录,然后用instance参数传给ModelForm——这样表单会自动填充用户上次选择的选项:
# views.py from django.shortcuts import render from django.utils import timezone from django.contrib.auth.decorators import login_required from django.http import HttpResponseRedirect from .forms import NameForm from .models import Eintrag @login_required() def get_name(request): # 先获取当前用户的已有记录 user_entry = Eintrag.objects.filter(Name=request.user).first() # 如果用外键,这里改成filter(user=request.user) if request.method == 'POST': # 绑定已有记录(如果存在),POST时直接更新而不是新建 form = NameForm(request.POST, instance=user_entry) if form.is_valid(): eintrag = form.save(commit=False) eintrag.Name = request.user # 如果用外键,这一步可以省略,instance已经关联用户 eintrag.pub_date = timezone.now() eintrag.save() return HttpResponseRedirect(request.path) else: # 如果有用户记录,用它初始化表单;否则创建空表单 form = NameForm(instance=user_entry) if user_entry else NameForm() return render(request, 'form/name.html', {'form': form, 'posts': user_entry})
为什么这样有效?
Django的ModelForm在接收instance参数时,会自动将该实例的字段值填充到表单对应的输入框中,完美实现“显示用户最新选择”的需求。同时,POST时用instance绑定,还能避免你之前先删除再新建的冗余操作,直接更新已有记录即可。
3. 表单部分无需修改
你的forms.py代码是正常的,不需要额外改动——ModelForm会自动根据模型的choices渲染下拉框,并且结合视图传入的instance填充默认值。
内容的提问来源于stack exchange,提问作者Sebastian
相关产品推荐
相关产品推荐

