Home > Net >  Field 'id' expected a number but got <category: python >
Field 'id' expected a number but got <category: python >

Time:08-13

I am trying to submit a form but the 'category' part of the form is saving. I am creating a notes application, in which a notes form consists of 3 items : Category , Topic and Notes. Category should be unique, if it already exists then add the 'Topic' in the existing Category else create a new category, and then add notes to it respectively.

Views.py

from django.shortcuts import render, redirect
from django.core.exceptions import ObjectDoesNotExist

from django.contrib.auth.models import User
# from django.contrib.auth.decorators import login_required
from .models import Category, Topic, Notes
# from .forms import RoomForm, UserForm

# from django.contrib.auth import authenticate, login, logout
# from django.contrib.auth.forms import UserCreationForm

# from django.contrib import messages

# Create your views here.
def home(request):
    context = {}
    return render(request, "base/home.html",context)


def make_notes(request):
    categories = Category.objects.all()
    topics = Topic.objects.all()
    notes = Notes.objects.all()
    if request.method == 'POST':
        categories = Category.objects.get_or_create(
            category = request.POST.get('category')
        )       
        topics = Topic.objects.get_or_create(
            category_name = categories,
            name = request.POST.get('topic')
        )
        notes = Notes.objects.get_or_create(
            topic_name = topics,
            body = request.POST.get('body')
        )
        return redirect('notes')
    context = {'categories':categories,'topics':topics,'notes':notes}
    return render(request,'base/notes.html',context)

Models.py

from django.db import models

# Create your models here.
from django.contrib.auth.models import User

class Category(models.Model):
    category = models.CharField(unique=True, max_length=200)

    def __str__(self) -> str:
        return self.category


class Topic(models.Model):
    category_name = models.ForeignKey(Category, on_delete=models.CASCADE)
    name = models.CharField(max_length=200)
    # description = models.TextField(null=True, blank=True)
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-updated','-created']

    def __str__(self):
        return self.name

class Notes(models.Model):
    topic_name = models.ForeignKey(Topic, on_delete=models.CASCADE)
    body = models.TextField()
    updated = models.DateTimeField(auto_now=True)
    created = models.DateTimeField(auto_now_add=True)

    class Meta:
        ordering = ['-updated','-created']

    def __str__(self):
        return self.body[0:20]

On page we click, make notes and this redirects us to Notes.html.

Notes.html

{% extends 'base/main.html' %}
{% block content %}

<div >
    <div >
        <h2><strong>Notes</strong></h2>
        <!-- will show sample notes if not logged in -->
        <form action="" method="post">
            {% csrf_token %}
            <label for="">Enter a category</label>
            <input type="text" name="category">

            <label for="">Write your topic name...</label>
            <input type="text" name="topic">

            <label for="">Start noting here</label>
            <input type="text" name="body">

            <button type="submit">Submit</button>
        </form>
        <br><hr><br>
        {% for note in notes %}
            <h1>Category : {{note.topic_name.category_name}}</h1>
            <p>Created {{note.created|timesince}} ago</p>
            <h3>
                {{note.topic_name}}
            </h3>
            <p>
                {{note.body}}
            </p>
            <br>
        {% endfor %}
    </div>
    
    <div >
        <h2><strong>Categories</strong></h2>
        {% for category in categories %}
            <p>{{category}}</p>
        {% endfor %}
    </div>
</div>

{% endblock %}

Home page:

{% extends "base/main.html" %}
{% block content %}

<div >
    <div >
        <h2><strong>
            <a href="{% url 'notes' %}"> Make Notes</a>
        </strong></h2>
        <!-- will show sample notes if not logged in -->
    </div>
    
    <div >
        <h2><strong>Categories</strong></h2>
    </div>
</div>

{% endblock content %}

Notes page: Notes page image

Error :

This is the Error showing

Error in topics variable

Please help me , what am I missing? Also please guide me a source of learning Django after which I don't make at least these types of mistakes. Thank you in advance.

Here: Changes made in views.py

def make_notes(request):
    categories = Category.objects.all()
    topics = Topic.objects.all()
    notes = Notes.objects.all()
    if request.method == 'POST':
        categories = Category.objects.get_or_create(
            category = request.POST.get('category')
        )       
        topics, created = Topic.objects.get_or_create(
            category_name = categories,
            name = request.POST.get('topic')
        )
        notes, created = Notes.objects.get_or_create(
            topic_name = topics,
            body = request.POST.get('body')
        )
        return redirect('notes')
    context = {'categories':categories,'topics':topics,'notes':notes}
    return render(request,'base/notes.html',context)

Complete traceback:

Environment:


Request Method: POST
Request URL: http://127.0.0.1:8000/notes/

Django Version: 4.1
Python Version: 3.9.10
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'base.apps.BaseConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\fields\__init__.py", line 2018, in get_prep_value
    return int(value)

The above exception (int() argument must be a string, a bytes-like object or a number, not 'Category') was the direct cause of the following exception:
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "C:\Users\shiva\Desktop\proj\todo_list\base\views.py", line 28, in make_notes
    topics, created = Topic.objects.get_or_create(
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 928, in get_or_create
    return self.get(**kwargs), False
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 636, in get
    clone = self._chain() if self.query.combinator else self.filter(*args, **kwargs)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 1420, in filter
    return self._filter_or_exclude(False, args, kwargs)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 1438, in _filter_or_exclude
    clone._filter_or_exclude_inplace(negate, args, kwargs)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\query.py", line 1445, in _filter_or_exclude_inplace
    self._query.add_q(Q(*args, **kwargs))
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 1532, in add_q
    clause, _ = self._add_q(q_object, self.used_aliases)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 1562, in _add_q
    child_clause, needed_inner = self.build_filter(
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 1478, in build_filter
    condition = self.build_lookup(lookups, col, value)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\sql\query.py", line 1303, in build_lookup
    lookup = lookup_class(lhs, rhs)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\lookups.py", line 27, in __init__
    self.rhs = self.get_prep_lookup()
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\fields\related_lookups.py", line 166, in get_prep_lookup
    self.rhs = target_field.get_prep_value(self.rhs)
  File "C:\Users\shiva\AppData\Local\Programs\Python\Python39\lib\site-packages\django\db\models\fields\__init__.py", line 2020, in get_prep_value
    raise e.__class__(

Exception Type: TypeError at /notes/
Exception Value: Field 'id' expected a number but got <Category: Django>.

CodePudding user response:

I guess problem is here:

    categories = Category.objects.get_or_create(
        category = request.POST.get('category')
    )  

Because you use get_or_create, you get tuple in categories variable. and then trying to set this tuple as category_name when creating Topic that lead to error.

See docs get_or_create.

Returns a tuple of (object, created), where object is the retrieved or created object and created is a boolean specifying whether a new object was created.

So just change it on:

    categories, created = Category.objects.get_or_create(
        category = request.POST.get('category')
    ) 

CodePudding user response:

Change you make_notes view code to this:


def make_notes(request):
    categories = Category.objects.all()
    topics = Topic.objects.all()
    notes = Notes.objects.all()
    if request.method == 'POST':
        categories, created = Category.objects.get_or_create(
            category = request.POST.get('category')
        )  
        topics, created = Topic.objects.get_or_create(
            category_name_id = categories.id,
            name = request.POST.get('topic')
        )
        notes, created = Notes.objects.get_or_create(
            topic_name_id = topics.id,
            body = request.POST.get('body')
        )
        return redirect('notes')
    context = {'categories':categories,'topics':topics,'notes':notes}
    return render(request,'base/notes.html',context)

You can follow this documentation: https://docs.djangoproject.com/en/4.1/ref/models/querysets/#get-or-create

  • Related