Search code examples
pythondjangoforeign-keysvalueerror

Field 'id' expected a number but got 'natsu' django


I want to create a user_posts view that has all the posts related to a particular user let's say there is/are blog posts written by a user 'Natsu' then a logged-in user let's say 'Testuser' will be able to see all posts by that user i.e. all posts of user 'Natsu'.

blog models.py

class Post(models.Model):
  title = models.CharField(max_length=250)
  slug = models.SlugField(max_length=250, unique_for_date='publish')
  author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='blog_posts')
  body = models.TextField()

user models.py

class Profile(models.Model):
  user = models.OneToOneField(User, on_delete=models.CASCADE)
  image = models.ImageField(upload_to='profile_pic', default='default.jpg')

  def __str__(self):
    return f'{ self.user.username } Profile'

views.py

def user_posts(request, username):
  posts = Post.objects.filter(author=username)
  return render(request, 'blog/user_posts.html', {'posts':posts})

user_posts.html

{% for post in posts %}
      <a href="{% url 'user-posts' post.author.username %}" class="mr-2">{{ post.author }}</a>
      <h2><a href="{% url 'post-detail' post.pk %}">{{ post.title }}</a></h2>
      {{ post.body|truncatewords:30 }} 
{% endfor %}

urls.py

  path('user/<str:username>/', views.user_posts, name='user-posts'),

but when I go to that url it shows me error Field 'id' expected a number but got 'admin'.

full traceback is here:

Internal Server Error: /user/natsu/
Traceback (most recent call last):
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\__init__.py", line 1772, in get_prep_value
    return int(value)
ValueError: invalid literal for int() with base 10: 'natsu'

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

Traceback (most recent call last):
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\exception.py", line 34, in inner     
    response = get_response(request)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 115, in _get_response 
    response = self.process_exception_by_middleware(e, request)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\core\handlers\base.py", line 113, in _get_response 
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\Sheraram Prajapat\OneDrive\Desktop\Virtual Environment\mysite\blog\views.py", line 78, in user_posts
    posts = Post.published.filter(author=username)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\manager.py", line 82, in manager_method  
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\query.py", line 904, in filter
    return self._filter_or_exclude(False, *args, **kwargs)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\query.py", line 923, in _filter_or_exclude
    clone.query.add_q(Q(*args, **kwargs))
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\sql\query.py", line 1350, in add_q       
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\sql\query.py", line 1377, in _add_q      
    child_clause, needed_inner = self.build_filter(
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\sql\query.py", line 1311, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\sql\query.py", line 1165, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\lookups.py", line 22, in __init__        
    self.rhs = self.get_prep_lookup()
  File "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\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 "C:\Users\Sheraram Prajapat\AppData\Local\Programs\Python\Python38\lib\site-packages\django\db\models\fields\__init__.py", line 1774, in get_prep_value
    raise e.__class__(
ValueError: Field 'id' expected a number but got 'natsu'.
[29/Jun/2020 17:47:37] "GET /user/natsu/ HTTP/1.1" 500 127097

where am I doing wrong? Is there any other alternative?


Solution

  • author on Post would be the primary key of the User table which is an integer (unless modified from the default) and not the username. You either need to look up the username first is User or use some other Django 'magic'. Maybe try one of these (I think they both do the same thing in the backend):

    posts = Post.objects.filter(author=User.object.filter(username=username)[:1])
    

    or

    posts = Post.objects.filter(author__username=username)
    

    (I didn't test either... so please free to edit this answer or comment if either don't work)