Фреймворк Django API для публикации не работает?

#python #django

Вопрос:

У меня есть следующий код:

models.py

 class DeviceDetail(models.Model):
    
    SUBNET_CHOICES = (
    ('16','16'),
    ('17', '17'),
    ('18','18'),
    ('19','19'),
    ('20','20'),
    ('21', '21'),
    ('22', '22'),
    ('23', '23'),
    ('24', '24'),
    ('25', '25'),
    ('26', '26'),
    ('27', '27'),
    ('28', '28'),
    ('29', '29'),
    ('30', '30'),
    )

    DEV_MODS =(
        ('Catalyst 9606R', 'Catalyst 9606R'),
        ('C9300L-48T-4X', 'C9300L-48T-4X')
    )

    
    mgt_interface = models.CharField(max_length=50)
    subnetmask = models.CharField(max_length=2, choices = SUBNET_CHOICES)
    ssh_id = models.CharField(max_length=50)
    ssh_pwd = models.CharField(max_length=50)
    enable_secret = models.CharField(max_length=50)
    dev_mod=models.CharField(max_length=50, choices = DEV_MODS) ##device_model replacement
    DD2DKEY = models.ForeignKey(Device, on_delete=models.CASCADE) ##The key to link up the tables
    
    def __str__(self):
        return self.hostname
 

serializers.py

 class DeviceDetailSerializers(serializers.ModelSerializer):
    class Meta:
        model = DeviceDetail
        fields = ['mgt_interface', 'subnetmask', 'ssh_id', 'ssh_pwd', 'enable_secret', 'dev_mod']
 

views.py

 @api_view(['PUT'])
def update_device(request, pk=None):
    if pk != None:
        devicedetail = DeviceDetail.objects.filter(DD2DKEY=pk)
        devdserializer = DeviceDetailSerializers(devicedetail, data = request.data)
        if devdserializer.is_valid():           
            devdserializer.save() 
            results = {            
                "device_details" : devdserializer.data,
            }
            return Response(results, status=status.HTTP_201_CREATED)        
        return Response(devdserializer.errors, status=status.HTTP_400_BAD_REQUEST)
 

Код кажется мне правильным, но всякий раз, когда я пытался использовать почтальона для выполнения PUT, я получал ошибку 500. Я не понимаю, почему это происходит. Для кода я использую https://www.youtube.com/watch?v=B65zbFro2pU чтобы подсказать мне, как писать код, поскольку я новичок в этой структуре. Может ли кто-нибудь посоветовать мне, что делать, чтобы устранить эту ошибку? Большое спасибо.

Вот моя обратная связь в powershell:

 Internal Server Error: /devicelist/196/update
Traceback (most recent call last):
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesdjangocorehandlersexception.py", line 47, in inner
    response = get_response(request)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesdjangocorehandlersbase.py", line 181, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesdjangoviewsdecoratorscsrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesdjangoviewsgenericbase.py", line 70, in view
    return self.dispatch(request, *args, **kwargs)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkviews.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkviews.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkviews.py", line 480, in raise_uncaught_exception
    raise exc
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkviews.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkdecorators.py", line 50, in handler
    return func(*args, **kwargs)
  File "C:Interndjango_swinginterfaceviews.py", line 1036, in update_device
    devdserializer.save()
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkserializers.py", line 200, in save
    self.instance = self.update(self.instance, validated_data)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkserializers.py", line 970, in update
    info = model_meta.get_field_info(instance)
  File "C:UsersP1338475.virtualenvsdjango_swing-t91g66f4libsite-packagesrest_frameworkutilsmodel_meta.py", line 35, in get_field_info
    opts = model._meta.concrete_model._meta
AttributeError: 'QuerySet' object has no attribute '_meta'
 

Комментарии:

1. DeviceDetail.objects.filter(DD2DKEY=pk) возвращает список DeviceDetail s. Сериализатор, который у вас в настоящее время, ожидает только один экземпляр. Вы хотели использовать get ? Итак: DeviceDetail.objects.get(DD2DKEY=pk) ?

2. Старайтесь избегать использования прописных букв для имени поля в модели. Они предназначены для констант или имен классов.

3. Я использую .get , и это сработало. Спасибо за предложение и объяснение @BrianD

Ответ №1:

 Use:
devicedetail = DeviceDetail.objects.get(DD2DKEY=pk)
instead of
devicedetail = DeviceDetail.objects.filter(DD2DKEY=pk)
 

Потому filter что вернет список объектов и get вернет один объект
В вашем случае вы просто обновляете один экземпляр.

Если вы хотите обновить все экземпляры, используйте

 devdserializer = DeviceDetailSerializers(devicedetail, data = request.data,many=True)