Поле «идентификатор» ожидало номер, но получило «Генри» (AJAX и DRF)

#django #ajax #django-rest-framework

Вопрос:

Я пытаюсь получить список пользователей с запросом AJAX и DRF. Но получите эту ошибку:

 Field 'id' expected a number but got 'Henry'.
 

Я был бы благодарен за любую помощь.

АЯКС:

 const showUserLists = function(map){
  let userName = "Henry";

  $.ajax({
      type: 'GET',
      url: '/api/userlist/',
      data: {
        'username': userName
      },
      success: function (data) {
        data.forEach(item => { 
              console.log(item.list_name)
              $("#userLists").append("<li class=userlist data-name=""   item.list_name   "">"   item.list_name   "</li>")
          })
        }
      });
};
 

urls.py:

 router = DefaultRouter() #need help understanding router register
router.register('userlist', views.UserListViewSet, basename= 'userlist')
 

views.py

 #this shows all lists for a user
class UserListViewSet(viewsets.ModelViewSet):
    serializer_class = UserListSerializer
 
    def get_queryset(self):
        name = self.request.GET.get('username', None)
        return UserList.objects.filter(user=name)
 

Сериализатор:

 class UserListSerializer(serializers.ModelSerializer): #this is what we worked on on October 1
    class Meta:
        model = UserList
        fields = ['id', 'user', 'list_name']

class VenueListSerializer(serializers.ModelSerializer):
    created = serializers.ReadOnlyField()

    class Meta:
        model = VenueList
        fields = ['id', 'title']
 

Соответствующая модель:

 class UserList(models.Model):
    list_name = models.CharField(max_length=255)
    user = models.ForeignKey(User, on_delete=models.CASCADE) #is this okay?

    def __str__(self):
        return self.list_name
 

Обратная связь

 Traceback (most recent call last):
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1774, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: 'Henry'

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/core/handlers/exception.py", line 47, in inner
    response = get_response(request)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/core/handlers/base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/viewsets.py", line 114, in view
    return self.dispatch(request, *args, **kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 505, in dispatch
    response = self.handle_exception(exc)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 465, in handle_exception
    self.raise_uncaught_exception(exc)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 476, in raise_uncaught_exception
    raise exc
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/views.py", line 502, in dispatch
    response = handler(request, *args, **kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/rest_framework/mixins.py", line 38, in list
    queryset = self.filter_queryset(self.get_queryset())
  File "/Users/x/Desktop/Coding/anybody/anybody1/api/views.py", line 33, in get_queryset
    return UserList.objects.filter(user=name)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/query.py", line 942, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/query.py", line 962, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, *args, **kwargs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/query.py", line 969, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1358, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1380, in _add_q
    split_subq=split_subq, check_filterable=check_filterable,
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1319, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1165, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/lookups.py", line 24, in __init__
    self.rhs = self.get_prep_lookup()
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/fields/related_lookups.py", line 115, in get_prep_lookup
    self.rhs = target_field.get_prep_value(self.rhs)
  File "/Users/x/Desktop/Coding/anybody/avenv/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1778, in get_prep_value
    ) from e
ValueError: Field 'id' expected a number but got 'Henry'.
 

Ответ №1:

Ваша user модель относится ForeignKey к User модели, поэтому, если вы отфильтруете ее, она ожидает первичный ключ User , а не имя пользователя.

Однако вы можете отфильтровать имя пользователя, связанное User с:

 class UserListViewSet(viewsets.ModelViewSet):
    serializer_class = UserListSerializer
 
    def get_queryset(self):
        name = self.request.GET.get('username', None)
        return UserList.objects.filter(user__username=name) 

Примечание: Обычно лучше использовать settings.AUTH_USER_MODEL [Django-doc] для ссылки на модель пользователя, чем использовать User модель [Django-doc] напрямую. Для получения дополнительной информации вы можете ознакомиться с разделом «Ссылки на User модель» документации.

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

1. Спасибо, ты дважды выручил меня сегодня. Что касается вашей записки, это особенно важно? Создаю ли я уязвимости и т.д., Делая это так, как я это делаю?

2. @vygrdev: нет, это делает его более удобным, если позже вы измените пользовательскую модель на пользовательскую.

3. Спасибо, да, я планирую сделать это в конце концов. Спасибо, что предупредили. Функция работает так, как я планировал, еще раз спасибо вам за помощь.