Aditya
Aditya

Reputation: 33

Django TypeError when trying to save the model

I am trying to create a todo add but when I try to save my model it says todo got an unexpected keyword argument .

TypeError at /
todo() got an unexpected keyword argument 'user'

it throws the following error

My models.py

class todo(models.Model):
   user = models.ForeignKey(User, on_delete=models.CASCADE)
   title = models.CharField(max_length=100)
   description = models.TextField()
   date= models.DateTimeField(auto_now = True)
   is_completed = models.BooleanField(default=False)


   def __str__(self):
      return self.user.username + self.title

And my views looks like this

def todo(request):
  if request.method == "POST":
    title = request.POST.get('title')
    description = request.POST.get('description')
    todo_list = todo(user=request.user, title=title, description= description)
    todo_list.save()
    messages.success(request, 'Successfully Created')
return render(request, 'main/todo.html')

Please help me out

Upvotes: 1

Views: 203

Answers (1)

willeM_ Van Onsem
willeM_ Van Onsem

Reputation: 476594

Both your model and the view are named todo, so if you call todo in that view, the function will override the model, and thus make a recursive call.

You can import todo with a different name, like:

from app_name.models import todo as todo_model

def todo(request):
  if request.method == 'POST':
    title = request.POST.get('title')
    description = request.POST.get('description')
    todo_list = todo_model.objects.create(
        user=request.user,
        title=title,
        description= description
    )
    messages.success(request, 'Successfully Created')
return render(request, 'main/todo.html')

But according to the PEP-8 style guidelines, classes are written in PerlCase, not snake_case. You thus might want to rename your model to:

class Todo(models.Model):
   user = models.ForeignKey(User, on_delete=models.CASCADE)
   title = models.CharField(max_length=100)
   description = models.TextField()
   date= models.DateTimeField(auto_now = True)
   is_completed = models.BooleanField(default=False)


   def __str__(self):
      return self.user.username + self.title

and then you can work with:

from app_name.models import Todo

def todo(request):
  if request.method == 'POST':
    title = request.POST.get('title')
    description = request.POST.get('description')
    todo_list = Todo.objects.create(
        user=request.user,
        title=title,
        description= description
    )
    messages.success(request, 'Successfully Created')
return render(request, 'main/todo.html')

Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.


Note: You can limit views to a view to authenticated users with the @login_required decorator [Django-doc].


Note: It is better to use a Form [Django-doc] than to perform manual validation and cleaning of the data. A Form will not only simplify rendering a form in HTML, but it also makes it more convenient to validate the input, and clean the data to a more convenient type.

Upvotes: 2

Related Questions