I'm working on a Django Webapp, and I have a pesky error message. It is "TypeError: expected string or bytes-like object".
Relevant code follows, analysis below.
Full traceback
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/exception.py", line 39, in inner
response = get_response(request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
response = self.process_exception_by_middleware(e, request)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/contrib/auth/decorators.py", line 23, in _wrapped_view
return view_func(request, *args, **kwargs)
File "/Users/Philip/Code/GrammieGram/grams/views.py", line 83, in gramsindex
grams_list = grams_list.filter(display_until=[start_time, end_time])
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site- packages/django/db/models/query.py", line 796, in filter
return self._filter_or_exclude(False, *args, **kwargs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/query.py", line 814, in _filter_or_exclude
clone.query.add_q(Q(*args, **kwargs))
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1227, in add_q
clause, _ = self._add_q(q_object, self.used_aliases)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1253, in _add_q
allow_joins=allow_joins, split_subq=split_subq,
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1187, in build_filter
condition = self.build_lookup(lookups, col, value)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/sql/query.py", line 1083, in build_lookup
return final_lookup(lhs, rhs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/lookups.py", line 19, in __init__
self.rhs = self.get_prep_lookup()
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/lookups.py", line 59, in get_prep_lookup
return self.lhs.output_field.get_prep_value(self.rhs)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1417, in get_prep_value
value = super(DateTimeField, self).get_prep_value(value)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1275, in get_prep_value
return self.to_python(value)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/fields/__init__.py", line 1378, in to_python
parsed = parse_datetime(value)
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/utils/dateparse.py", line 93, in parse_datetime
match = datetime_re.match(value)
TypeError: expected string or bytes-like object
[22/Jun/2017 01:55:31] "GET /robin/grams/ HTTP/1.1" 500 125650
Forms.py
from django import forms
import math
import datetime
from django.utils import timezone
from delorean import Delorean
from .models import Gram
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class MessageForm(forms.Form):
message = forms.CharField(max_length=141)
delete_delta = forms.DecimalField(min_value = .01)
def save(self, request):
data = self.cleaned_data
def convert_time(num):
minutes = math.ciel(num*60)
return minutes
now = Delorean()
now = st_input.truncate("minute")
now = now.datetime
gram = Gram(message=data['message'], username=request.user.username, sent_time=now, display_until=now+datetime.timedelta(minutes=convert_time(data['delete_delta'])))
gram.save()
models.py
from django.db import models
from django.contrib.auth.models import User
from django.utils import timezone
import datetime
class Gram(models.Model):
message = models.CharField(max_length=141)
username = models.CharField(max_length=100, default="default")
sent_time = models.DateTimeField(null=True)
display_until = models.DateTimeField(null=True)
def __str__(self):
return self.message
views.py
from django.shortcuts import get_object_or_404, render, redirect
from django.http import HttpResponseRedirect, HttpResponse
from django.urls import reverse
from django.views import generic
from django.utils import timezone
import datetime
from delorean import Delorean
from .models import Gram
from .forms import MessageForm, SignUpForm
from django.contrib.auth import login, authenticate, update_session_auth_hash
from django.contrib.auth.models import User
from django.contrib import messages
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.decorators import login_required
@login_required
def gramsindex(request, username):
u = request.user.username
new = '/{0}/new/'.format(u)
account = '/{0}/account/'.format(u)
cp = '/{0}/change_password/'.format(u)
grams_list = Gram.objects.order_by('-sent_time')
grams_list = grams_list.filter(username=username)
start_time = Delorean()
start_time = start_time.truncate("minute")
start_time = str(start_time.datetime)
end_time = Delorean()+datetime.timedelta(days=100)
end_time = end_time.truncate("minute")
end_time = str(end_time.datetime)
grams_list = grams_list.filter(display_until=[start_time, end_time])
context = {'grams_list': grams_list}
return render(request, 'grams/index.html', context)
What I am trying to do is filter the messages (called grams) by their display until date time. This comes as a user input as a number, which I pass into the model save function as part of a time delta. I only want to show grams whose display until property is after right now. I am currently using Delorean to make the time objects easier to work with, I don't think that's what's causing the problem.
I looked at the following questions: expected string or buffer ,date_re.match(value) django error , Django DateTimeField TypeError: expected string or bytes-like object , Django datetime migration error
I did everything that they recommend: make new migrations, change defaults to timezone.now, make the DateTimeFields nullable. None of it works. From what I understand from tracing the error through the Django source code, there is a parsing function that takes a date time-object or a string and parses it into a date time object. This is what is causing the problem.
Where should I go from here? Is there some little thing that I can fix, or is there a better way to filter so that it only displays the grams with a display until property that is after right now?