Django Rest Framework函数视图如何给模型created_by字段自动赋值登录用户
问题根因
你遇到的报错是因为新增房产数据时created_by字段没有被赋值,触发了数据库非空约束,同时你的模型字段还存在配置错误:created_by是外键字段,不应该设置字符串类型的默认值default=''。
修复步骤
1. 修正模型字段配置
删除created_by字段错误的默认值配置,修改后代码如下:
from django.db import models from django.conf import settings class RentalProperties(models.Model): property_name = models.CharField(max_length=255) property_type = models.CharField(choices=TYPE, max_length=255) property_location = models.CharField(max_length=255) county = models.CharField(choices=COUNTY, max_length=255) number_of_units = models.IntegerField() # 删掉错误的default='',外键字段不能用字符串作为默认值 created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE) date_created = models.DateField(auto_now_add=True) last_modified = models.DateField(auto_now=True) def __str__(self): return self.property_name class Meta: verbose_name_plural = "Properties"
修改完成后重新生成并执行迁移:
- 如果是开发环境,可以直接删除
Properties应用migrations目录下除__init__.py之外的文件,再执行python manage.py makemigrations和python manage.py migrate - 如果是生产环境有存量数据,可以先临时将字段改为
created_by = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True),填充完历史数据的created_by值后再改回非空约束。
2. 调整序列化器配置
将created_by设为只读字段,不需要前端传参,也避免前端恶意篡改赋值:
from apps.Properties.models import RentalProperties from rest_framework import serializers class PropertiesSerializers(serializers.ModelSerializer): class Meta: model = RentalProperties fields = ('id', 'property_name', 'property_type', 'property_location', 'county', 'number_of_units', 'created_by', 'date_created', 'last_modified') # 新增只读字段配置 read_only_fields = ('created_by',)
3. 修改函数式API视图
首先给接口增加登录校验,然后在调用序列化器save方法时,将当前登录用户作为额外参数传入,自动完成created_by的赋值:
from rest_framework.permissions import IsAuthenticated @login_required(login_url='Login' ) def AllProperties(request): return render(request, 'Dashboard - Properties.html') @api_view(['POST']) # 新增登录权限校验,确保只有登录用户可以调用接口 @permission_classes([IsAuthenticated]) def AddPropertyAPI(request): serializer = PropertiesSerializers(data=request.data) if serializer.is_valid(raise_exception=True): # save时传入额外参数,自动赋值给对应的模型字段 serializer.save(created_by=request.user) return Response(serializer.data, status=status.HTTP_201_CREATED) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
补充说明(可选)
如果你需要在Django原生admin后台提交房产数据时也自动填充created_by,可以在admin注册类中重写save_model方法:
from django.contrib import admin from .models import RentalProperties @admin.register(RentalProperties) class RentalPropertiesAdmin(admin.ModelAdmin): exclude = ('created_by',) # 后台表单隐藏该字段 def save_model(self, request, obj, form, change): if not change: # 只有新增时赋值 obj.created_by = request.user super().save_model(request, obj, form, change)
内容的提问来源于stack exchange,提问作者CoderS
相关产品推荐
相关产品推荐

