Я использую 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'
Честно говоря, я был смущен этим полем "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)
Наконец, URL:
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)