如何在Django表单中预填充当前登录用户并隐藏用户下拉框
问题
我希望在HTML页面预填充司机注册时已填写的信息(如username),目前除user字段外其他字段均能正常预填充,但user字段显示所有用户的下拉列表。我已尝试在forms.py的__init__方法中设置值,以及新增CharField,但均未成功。相关代码如下,请求帮助实现仅显示当前登录用户而非全部用户的效果:
urls.py
path('driver_info/', driver_info, name='driver_info'),
views.py
@login_required(login_url='login') def driver_info(request): p_form = DriverUserInfoForm(instance=request.user.driverprofile) context = { 'p_form' : p_form } return render(request, 'driver/driver_info.html', context)
models.py
class DriverProfile(models.Model): user = models.OneToOneField(CustomUser, on_delete=models.CASCADE) is_verified = models.BooleanField(default=False) is_active = models.BooleanField(default=False) driving_license_number = models.CharField(max_length=25, unique=True, verbose_name="DL Number") expiry_date = models.DateField(verbose_name="DL Expiry Date") def __str__(self): return self.user.username
forms.py
class DriverUserInfoForm(forms.ModelForm): class Meta: model = DriverProfile exclude = ('is_verified', 'is_active',)
driver_info.html
{% block content %} <h3>Driver info</h3> <form action="" method="POST"> {% csrf_token %} {{ p_form }} <input type="submit" value="Next" /> </form> {% endblock %}
users/models.py
class CustomUser(AbstractUser): mobile_no = models.CharField(max_length=12) def __str__(self): return self.username
解决方案
方法一:过滤user字段选项并设置为只读
这种方法保留user字段的表单结构,但仅显示当前登录用户,且禁止修改:
修改forms.py:
from django import forms from .models import DriverProfile from users.models import CustomUser class DriverUserInfoForm(forms.ModelForm): class Meta: model = DriverProfile exclude = ('is_verified', 'is_active',) def __init__(self, *args, **kwargs): # 从参数中取出request对象 self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) # 仅当用户已登录时过滤选项 if self.request and self.request.user.is_authenticated: self.fields['user'].queryset = CustomUser.objects.filter(id=self.request.user.id) # 设置字段为只读,无法修改 self.fields['user'].disabled = True
修改views.py,实例化表单时传入request参数:
@login_required(login_url='login') def driver_info(request): p_form = DriverUserInfoForm(instance=request.user.driverprofile, request=request) context = { 'p_form' : p_form } return render(request, 'driver/driver_info.html', context)
方法二:替换为只读用户名显示(更简洁)
如果不需要保留user字段的下拉结构,只想展示当前用户名且不允许修改,可以直接替换为只读字段:
修改forms.py:
from django import forms from .models import DriverProfile class DriverUserInfoForm(forms.ModelForm): # 新增只读字段展示用户名 username = forms.CharField(label='用户名', disabled=True) class Meta: model = DriverProfile # 排除原user字段 exclude = ('user', 'is_verified', 'is_active',) def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) if self.request and self.request.user.is_authenticated: # 预填充当前登录用户的用户名 self.fields['username'].initial = self.request.user.username
修改views.py,处理表单提交时手动关联用户:
@login_required(login_url='login') def driver_info(request): p_form = DriverUserInfoForm(instance=request.user.driverprofile, request=request) if request.method == 'POST': p_form = DriverUserInfoForm(request.POST, instance=request.user.driverprofile, request=request) if p_form.is_valid(): # 保存时手动绑定当前用户 profile = p_form.save(commit=False) profile.user = request.user profile.save() # 可在此添加提交后的跳转逻辑,比如redirect到首页 context = { 'p_form' : p_form } return render(request, 'driver/driver_info.html', context)
内容的提问来源于stack exchange,提问作者Shraddha Agrawal
相关产品推荐
相关产品推荐

