TypeError: 'NoneType' object is not subscr

2020-06-18 06:01发布

问题:

Using django. I have the following model:

class Postagem(models.Model):
id = models.AutoField(primary_key=True, editable=False)
descricao = models.CharField(max_length=50)
area = models.ForeignKey('core.Area', null=True)
user = models.ForeignKey('User')
categoria = models.CharField(max_length=50, null=True)
post = models.FileField(upload_to='posts/', null=True)
thumbnail = models.FileField(upload_to='posts/', null=True)


def __str__(self):
    return self.descricao

The Following form:

class PostForm(forms.ModelForm):
categoria = forms.ChoiceField(choices=[("Video","Vídeo"),("Audio","Aúdio"),("Imagem","Imagem"),("Musica","Música")], required=True)
thumbnail = forms.FileField(required=False)

class Meta:
    model = Postagem
    fields = ['descricao', 'area', 'user', 'post']

View:

def profileView(request):
context = getUserContext(request)

if request.method == 'POST':
    exception=None
    userDict = {}
    userDict["user"] = context["user"].id    
    if "categoria" in request.POST:
        newPost = request.POST.copy()
        newPost.update(userDict)
        form = PostForm(newPost,request.FILES)
        print("postform POST: ",newPost, " File ",request.FILES)
        if form.is_valid():
            print("valid")
            try:
                form.save()
                print("saved")
                return HttpResponseRedirect(reverse_lazy('accounts:profile'))
            except IntegrityError as e:
                print("Integrity Error")
                exception=e            
        else:
            print("PostForm error")
            print(form.errors)

    form.non_field_errors=form.errors
    if exception is not None:
        form.non_field_errors.update(exception)
    context['form']=form

posts = Postagem.objects.get_queryset().order_by('id')
paginator = Paginator(posts, 12)
page = request.GET.get('page')
context["areas"] = Area.objects.all()   
try:
    posts = paginator.page(page)
except PageNotAnInteger:
    # If page is not an integer, deliver first page.
    posts = paginator.page(1)
except EmptyPage:
    # If page is out of range (e.g. 9999), deliver last page of results.
    posts = paginator.page(paginator.num_pages)

context["posts"]=posts

return render(
    request,
    'accounts/profile.html',
    context
)

And at last the template:

 {% for post in posts %}
        {% if forloop.counter0|divisibleby:4 or forloop.counter0 == 0 %}    
        <div id="grid-profile" class="row grid">
            <div class="col-md-1"></div>
        {% endif %}

            {% ifnotequal post.categoria "Imagem"%}
            <iframe id=post{{forloop.counter}} width="420" height="315"
                src={{post.post.url}}>
            </iframe>
            {% else %}
            <div class="col-md-2">
                <button type="button" id="modal1trigger" data-toggle="modal" data-target="#modal1"><img class="img-responsive" src={{post.post.url}}></img></button>
            </div>
            {% endifnotequal %}

        {% if forloop.counter|divisibleby:4 or forloop.counter == posts|length %} 
            <div class="col-md-1"></div>
        </div>
        {% endif %}
        {% endfor %}
        <div class="pagination">
            <span class="step-links">
                {% if posts.has_previous %}
                    <a href="?page={{ posts.previous_page_number }}">previous</a>
                {% endif %}

                <span class="current">
                    Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
                </span>

                {% if posts.has_next %}
                    <a href="?page={{ posts.next_page_number }}">next</a>
                {% endif %} 
            </span>
        </div>

I cut some of the template... Anyways, I want to be able to add all kinds of posts. Songs, Videos, Images, Docs, etc. And it IS working. The posts are being added. But, I'm having a recurring error and I don't know why. That could be very dangerous so I started looking into it, but with no luck in finding an acceptable answer. The error only happens when trying to get a song or a video.

    [21/Sep/2017 23:32:44] "GET /media/posts/13567830_1641362072853439_1924036772_n.mp4 HTTP/1.1" 200 1171456
Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 138, in run
    self.finish_response()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish
_response
    self.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 279, in write
    self._write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 453, in _write

    result = self.stdout.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 775, in write
    self._sock.sendall(b)
ConnectionResetError: [WinError 10054] Foi forçado o cancelamento de uma conexão existente pelo host remoto
[21/Sep/2017 23:32:44] "GET /media/posts/13567830_1641362072853439_1924036772_n.mp4 HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 53113)
Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 138, in run
    self.finish_response()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish
_response
    self.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 279, in write
    self._write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 453, in _write

    result = self.stdout.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 775, in write
    self._sock.sendall(b)
ConnectionResetError: [WinError 10054] Foi forçado o cancelamento de uma conexão existente pelo host remoto

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 141, in run
    self.handle_error()
  File "C:\Users\eduardo\Envs\ProExC\lib\site-packages\django\core\servers\basehttp.py", line 88, in handle_erro
r
    super(ServerHandler, self).handle_error()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 368, in handle
_error
    self.finish_response()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish
_response
    self.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 274, in write
    self.send_headers()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 331, in send_h
eaders
    if not self.origin_server or self.client_is_modern():
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 344, in client
_is_modern
    return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 639, in process_re
quest_thread
    self.finish_request(request, client_address)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 361, in finish_req
uest
    self.RequestHandlerClass(request, client_address, self)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 696, in __init__
    self.handle()
  File "C:\Users\eduardo\Envs\ProExC\lib\site-packages\django\core\servers\basehttp.py", line 155, in handle
    handler.run(self.server.get_app())
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 144, in run
    self.close()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\simple_server.py", line 35, in cl
ose
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
----------------------------------------
[21/Sep/2017 23:32:44] "GET /media/posts/03_-_The_Mute.mp3 HTTP/1.1" 200 1179648
Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 138, in run
    self.finish_response()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish
_response
    self.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 279, in write
    self._write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 453, in _write

    result = self.stdout.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 775, in write
    self._sock.sendall(b)
ConnectionResetError: [WinError 10054] Foi forçado o cancelamento de uma conexão existente pelo host remoto
[21/Sep/2017 23:32:44] "GET /media/posts/03_-_The_Mute.mp3 HTTP/1.1" 500 59
----------------------------------------
Exception happened during processing of request from ('127.0.0.1', 53114)
Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 138, in run
    self.finish_response()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish
_response
    self.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 279, in write
    self._write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 453, in _write

    result = self.stdout.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 775, in write
    self._sock.sendall(b)
ConnectionResetError: [WinError 10054] Foi forçado o cancelamento de uma conexão existente pelo host remoto

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 141, in run
    self.handle_error()
  File "C:\Users\eduardo\Envs\ProExC\lib\site-packages\django\core\servers\basehttp.py", line 88, in handle_erro
r
    super(ServerHandler, self).handle_error()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 368, in handle
_error
    self.finish_response()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 180, in finish
_response
    self.write(data)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 274, in write
    self.send_headers()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 331, in send_h
eaders
    if not self.origin_server or self.client_is_modern():
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 344, in client
_is_modern
    return self.environ['SERVER_PROTOCOL'].upper() != 'HTTP/0.9'
TypeError: 'NoneType' object is not subscriptable

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 639, in process_re
quest_thread
    self.finish_request(request, client_address)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 361, in finish_req
uest
    self.RequestHandlerClass(request, client_address, self)
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\socketserver.py", line 696, in __init__
    self.handle()
  File "C:\Users\eduardo\Envs\ProExC\lib\site-packages\django\core\servers\basehttp.py", line 155, in handle
    handler.run(self.server.get_app())
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\handlers.py", line 144, in run
    self.close()
  File "c:\users\eduardo\appdata\local\programs\python\python36-32\Lib\wsgiref\simple_server.py", line 35, in cl
ose
    self.status.split(' ',1)[0], self.bytes_sent
AttributeError: 'NoneType' object has no attribute 'split'
---------------------------------------

Edit:

Using Django 1.11.3, Windows 10, Tested with Opera and Chrome, Running server using gulp

**Edit 2: **

Hey, the error ONLY HAPPENS if there is a iframe tag in the html!!

回答1:

It appears that its a python error:

Django ticket: https://code.djangoproject.com/ticket/26995 Python ticket: https://bugs.python.org/issue14574

Didn't managed to solve just yet, if I can I will edit this answer explaining in detail how to solve it.

Edit

It seems to be a error on chrome. It didn't come to me, 'cause I was using Opera, but opera uses chromium as well. In internet explorer the error didn't show.

https://code.djangoproject.com/ticket/21227#no1

This is the bug tracker



回答2:

the first error self.environ['SERVER_PROTOCOL'].upper() is failing because self.environ['SERVER_PROTOCOL'] is None, and you can't do None.upper() you can only do .upper() on strings (as far as i'm aware).

the second error self.status.split(' ',1)[0], self.bytes_sent AttributeError: 'NoneType' object has no attribute 'split' This is failing because you self.status is None and you can't do None.split(), again this should be a string.

So it looks like some of the required values for these classes aren't being initialised or passed through.

It looks like the issue is with Django.core and WSGIref, so either the configuration isn't correct or perhaps there's an issue with the version you have installed?

Which version of Django are you running? Also are you running the server from ./manage.py runserver ?

[update 2017-09-28]

There's a couple of things I've modified, to start with I'm not copying the request.POST to a new dict, before passing it, this could be the cause of some of the values disappearing when trying to process a post.

I'm also passing user as a kwarg to your form, rather than trying to inject it into the copied POST.

mostly I've just updated some of the code to be a little easier to read, let's see how that goes.

# forms.py
class PostForm(forms.ModelForm):
    categoria = forms.ChoiceField(choices=[("Video","Vídeo"),("Audio","Aúdio"),("Imagem","Imagem"),("Musica","Música")], required=True)
    thumbnail = forms.FileField(required=False)

    class Meta:
        model = Postagem
        fields = ['descricao', 'area', 'user', 'post']

    def __init__(self, *args, **kwargs):  # handle user kwarg
        if 'user' in kwargs.keys():
            self.user = kwargs.pop('user')
        super(PostForm, self).__init__(*args, **kwargs)

# views.py
def profileView(request):
    form = None    
    if request.method == 'POST':
        exception=None
        if "categoria" in request.POST:
            if request.user:
                form = PostForm(request.POST,request.FILES, user=request.user)  # pass user as a kwarg
                print("postform POST: ",newPost, " File ",request.FILES)
                if form.is_valid():
                    print("valid")
                    try:
                        form.save()
                        print("saved")
                        return HttpResponseRedirect(reverse_lazy('accounts:profile'))
                    except IntegrityError as e:
                        print("Integrity Error")
                        exception=e            
                else:
                    print("PostForm error")
                    print(form.errors)
                #form has been indented as previously it would have been called before being initialised
                form.non_field_errors=form.errors
                if exception is not None:
                    form.non_field_errors.update(exception)
    posts = Postagem.objects.get_queryset().order_by('id')
    paginator = Paginator(posts, 12)
    page = None
    if request.GET:
        page = request.GET.get('page')
    areas = Area.objects.all()   
    try:
        posts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        posts = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        posts = paginator.page(paginator.num_pages)
    #return values    
    return render(
        request,
        'accounts/profile.html',
        {
            'form': form,
            'areas': areas,
            'posts': posts,
        }
    )


回答3:

Are you using PostgreSQL? It could be caused by a code page error.

C:\>psql -U postgres
psql (10.5)
WARNING: Console code page (850) differs from Windows code page (1252)
         8-bit characters might not work correctly. See psql reference
         page "Notes for Windows users" for details.
Type "help" for help.

postgres=#

Trying setting the code page before you start Django.

cmd.exe /c chcp 1252