Django问题:使用CreateView提交表单时对象未保存至数据库
解决CreateView提交无响应及字段权限控制问题
核心问题分析
- 提交无响应原因:
booking_fee_per_hour是模型必填字段(未设置blank=True),但你手动渲染的表单里未包含该字段,导致表单验证失败,且模板未显示错误信息,看起来像无反应。 - 字段权限需求:需要让普通用户看不到
slug和booking_fee_per_hour,仅管理员可见并编辑。
解决方案步骤
1. 自定义ModelForm控制字段显示
新建forms.py(如果没有),根据用户权限动态调整表单字段:
from django import forms from django.utils.text import slugify from .models import Artist class ArtistForm(forms.ModelForm): class Meta: model = Artist # 普通用户默认可见字段 fields = ['name', 'age', 'location', 'bio'] def __init__(self, *args, **kwargs): # 从参数中取出当前用户 user = kwargs.pop('user', None) super().__init__(*args, **kwargs) # 如果是管理员,添加管理员专属字段 if user and user.is_staff: self.fields['slug'] = forms.SlugField(required=False) self.fields['booking_fee_per_hour'] = forms.PositiveIntegerField( label="Booking Fee per hour", required=True ) # 调整字段顺序,把管理员字段放到前面 self.fields.move_to_end('slug', last=False) self.fields.move_to_end('booking_fee_per_hour', last=False)
2. 修改CreateView视图
更新views.py,使用自定义表单并处理普通用户的必填字段填充:
class ArtistsAddView(views.CreateView): template_name = 'add_artist.html' model = Artist form_class = ArtistForm # 替换为自定义表单 success_url = '/' def get_form_kwargs(self): # 将当前用户传递给表单 kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user return kwargs def form_valid(self, form): # 普通用户提交时,自动填充管理员专属字段 if not self.request.user.is_staff: # 自动生成唯一slug(可根据需求调整逻辑) base_slug = slugify(form.cleaned_data['name']) slug = base_slug counter = 1 while Artist.objects.filter(slug=slug).exists(): slug = f"{base_slug}-{counter}" counter += 1 form.instance.slug = slug # 设置booking_fee_per_hour默认值(根据业务需求修改) form.instance.booking_fee_per_hour = 0 return super().form_valid(form)
3. 优化模板显示错误信息
修改add_artist.html,添加错误提示并使用表单自动渲染(自动适配用户权限):
<form method="post" action="{% url 'artist add' %}"> {% csrf_token %} <!-- 显示表单全局错误 --> {% if form.non_field_errors %} <div style="color: red;">{{ form.non_field_errors }}</div> {% endif %} <!-- 自动渲染字段:普通用户只看到基础字段,管理员看到全部 --> {{ form.as_p }} <input type="hidden" name="next" value="{{ next }}"> <button type="submit">Submit</button> </form>
补充说明
- Slug唯一性:上述代码中手动处理了slug的唯一性,也可以使用
django-autoslug库简化这一步骤。 - Booking Fee默认值:根据你的业务逻辑调整
form.instance.booking_fee_per_hour的默认值,或给模型添加blank=True, null=True允许空值(不推荐必填字段留空)。 - 权限验证:如果需要限制普通用户的访问权限,可以在视图中添加
@login_required或自定义权限装饰器。
内容的提问来源于stack exchange,提问作者prsnr
相关产品推荐
相关产品推荐

