You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 03:38:25