我正在使用django-restframework。我遇到了一个非常奇怪的问题,无法解决问题。我在验证后尝试访问“http://127.0.0.1:8000/api/attendance/”时出现此问题:
Traceback:
File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\options.py" in get_field
566. return self.fields_map[field_name]
During handling of the above exception (True), another exception occurred:
File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\exception.py" in inner
35. response = get_response(request)
File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\base.py" in _get_response
158. response = self.process_exception_by_middleware(e, request)
File "C:\ProgramData\Anaconda3\lib\site-packages\django\core\handlers\base.py" in _get_response
156. response = response.render()
File "C:\ProgramData\Anaconda3\lib\site-packages\django\template\response.py" in render
106. self.content = self.rendered_content
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\response.py" in rendered_content
72. ret = renderer.render(self.data, accepted_media_type, context)
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\renderers.py" in render
724. context = self.get_context(data, accepted_media_type, renderer_context)
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\renderers.py" in get_context
656. raw_data_post_form = self.get_raw_data_form(data, view, 'POST', request)
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\renderers.py" in get_raw_data_form
572. data = serializer.data.copy()
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\serializers.py" in data
560. ret = super(Serializer, self).data
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\serializers.py" in data
266. self._data = self.get_initial()
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\serializers.py" in get_initial
413. for field in self.fields.values()
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\serializers.py" in fields
363. for key, value in self.get_fields().items():
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\serializers.py" in get_fields
1026. field_names, declared_fields, extra_kwargs
File "C:\ProgramData\Anaconda3\lib\site-packages\rest_framework\serializers.py" in get_uniqueness_extra_kwargs
1403. unique_constraint_field = model._meta.get_field(unique_constraint_name)
File "C:\ProgramData\Anaconda3\lib\site-packages\django\db\models\options.py" in get_field
568. raise FieldDoesNotExist("%s has no field named '%s'" % (self.object_name, field_name))
Exception Type: FieldDoesNotExist at /api/attendance/
Exception Value: Attendance has no field named 'True'
说实话,我对这个'真实'字段感到困惑。我完全无法摆脱困境。我尝试重新生成我的数据库并将相关字段设置为可选.etc。但是,它们都没有奏效。
这是我的代码:
models.py
class Attendance(models.Model):
A = 'a'
B = 'b'
C = 'c'
WORKPLACE_CHOICES = (
(A,'工作区 A'),
(B, '工作区 B'),
(C, '工作区 C')
)
work = models.TextField(blank=True,null=True)
student = models.ForeignKey('Student', blank = True, null=True,on_delete=models.CASCADE, related_name='attendances')
date = models.DateField(verbose_name='打卡日期',auto_now_add=True,unique_for_date=True)
start_work = models.DateTimeField(verbose_name='上班时间',null=True,blank=True)
off_work = models.DateTimeField(verbose_name='下班时间',blank=True,null=True)
is_late = models.BooleanField(verbose_name='是否迟到',default=False)
work_place = models.CharField(verbose_name='工作区',max_length=1, choices=WORKPLACE_CHOICES,default=A)
work_length = models.FloatField(verbose_name='工作时长',default=0,)
ip = models.GenericIPAddressField(verbose_name='签到 IP',blank=True,null=True)
def save(self, *args, **kwargs):
self.is_late = self.compute_is_late()
return super().save(*args,**kwargs)
def compute_is_late(self):
if not self.start_work:
return False
if self.start_work <= dt.datetime(
self.start_work.year,
self.start_work.month,
self.start_work.day,
self.student.start_work.hour,
self.student.start_work.minute
):
return False
else:
return True
def compute_ip(self, request):
if request.META.has_key('HTTP_X_FORWARDED_FOR'):
ip = request.META['HTTP_X_FORWARDED_FOR']
else:
ip = request.META['REMOTE_ADDR']
self.ip = ip
return self.save()
def compute_work_length(self):
"""这个方法需要手动调用"""
assert self.off_work, '请在“下班”之后再调用此字段'
hours = (self.off_work - self.start_work).total_seconds() / (60*60)
self.work_length =hours
return self.save()
def __str__(self):
return self.student.user.username + ' ' + str(self.date) + ' 考勤表'
class Student(models.Model):
M = 'man'
W = 'Wan'
GENDER_CHOICES = (
(M, '男'),
(W, '女')
)
name = models.CharField(verbose_name='姓名',max_length=20,null=True,blank=True)
email = models.EmailField(verbose_name='邮箱',blank=True,null=True)
start_work = models.TimeField(verbose_name='上班时间',default=dt.time(9,0))
gender = models.CharField(
verbose_name='性别',
max_length=3,
choices=GENDER_CHOICES,
blank=True,
null=True,
default=M
)
number = models.CharField(verbose_name='学号',max_length=30,blank=False,null=False)
grade = models.CharField(verbose_name='年级',max_length=30,null=True,blank=True)
college = models.CharField(
verbose_name='学院',
max_length=30,null=True,
blank=True
)
connect = models.TextField(
verbose_name='其它联系方式',
null=True,blank=True
)
user = models.OneToOneField(User, on_delete=models.CASCADE, null=True, blank=True, related_name='student')
def __str__(self):
return '学生 ' + self.user.username
def save(self, *args, **kwargs):
try:
user_obj = User.objects.get(username=self.number)
except User.DoesNotExist:
user_obj = User.objects.create_user(username=self.number,
password=self.number,
email=self.email)
self.user = user_obj
return super().save(*args,**kwargs)
这是相对序列化器。
serializers.py
class AttendanceSerializer(serializers.ModelSerializer):
class Meta:
model = Attendance
fields = ('start_work', 'off_work', 'work_place', 'work','ip','date')
read_only_fields = ('start_work','ip','date','id')
extra_kwargs = {
'start_work': {'default': dt.datetime.now()}
}
def create(self, validated_data):
request = self.context['request']
user = request.user
student = user.student
validated_data['start_work'] = dt.datetime.now()
validated_data['student'] = student
attendance = Attendance.objects.create(**validated_data)
attendance.compute_ip(request)
return attendance
def update(self, instance, validated_data):
if instance.off_work:
validated_data.pop('off_work')
super().update(instance, validated_data)
然后是观点:
class AttendanceViewSet(viewsets.ModelViewSet):
queryset = Attendance.objects.all()
serializer_class = AttendanceSerializer
def update(self, request, *args, **kwargs):
self.partial_update(request, *args, **kwargs)
最后是网址:
router = routers.SimpleRouter()
router.register('attendance', AttendanceViewSet,base_name='attendance')
urlpatterns = [
path('',home, name='home'),
path('admin/', admin.site.urls),
path('login/', LoginView.as_view(),name='login'),
path('api/',include(router.urls)),
path('student/', StudentView.as_view(),name='student')
]
urlpatterns += static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
答案 0 :(得分:1)
错误是由日期字段中的模型文件中的unique_for_date=True
引起的。
将其更改为date = models.DateField(verbose_name='打卡日期',auto_now_add=True)
可修复错误。
我猜你正在寻找的行为,但我认为你的意思是:
date = models.DateField(verbose_name='打卡日期',auto_now_add=True, unique=True)
在关于unique
和unique_for_date
的Django引用中,它声明unique是一个布尔值“如果为True,则该字段在整个表中必须是唯一的。”
但是unique_for_date
不是布尔值(因此当您将其设置为True时会出现错误),而是对不同字段的引用。
以下是DRF's tests中使用的示例:
class UniqueForDateModel(models.Model):
slug = models.CharField(max_length=100, unique_for_date='published')
published = models.DateField()
作为旁注,我调试错误的方法实际上与How to create a Minimal, Complete, and Verifiable example密切匹配。通过消除不会导致错误的事情,我能够确定原因是什么。