2016-03-18 6 views
3

ich bin neu in django und Python, ich bin nach einem django Tutorial und ich immer die folgenden FehlerIch halte den folgenden Fehler „lokalen Variable‚TOTAL_RESULTS‘vor der Zuweisung referenziert“ immer

UnboundLocalError at /blog/search/ 
local variable 'total_results' referenced before assignment 

heren meinen Code bekommen

def post_search(request): 
     form = SearchForm() 
     if 'query' in request.GET: 
      form = SearchForm(request.GET) 
      if form.is_valid(): 
       cd = form.cleaned_data 
       results = SearchQuerySet().models(Post)\ 
        .filter(content=cd['query']).load_all() 
       # count total results 
       total_results = results.count() 
     template = 'blog/post/search.html' 
     context = { 
      'form': form, 
      'cd': cd, 
      'results': results, 
      'total_results': total_results 
     } 
     return render(request, template, context) 

ich versuchte es auch wie diese origanally, weil das ist, wie das Tutorial hatte

return render(request, template, { 
    'form': form, 
    'cd': cd, 
    'results': results, 
    'total_results': total_results 
    }) 

aber das hat auch nicht funktioniert

Ich verstehe, was die Fehlermeldung sagt, aber das ist, wie das Tutorial es hat. Was ist die richtige Syntax, um dies zu erreichen? alle Anleitung ist willkommen EDIT

: hier ist die Code-Vorlage

{% extends "blog/base.html" %} 
     {% block title %}Search{% endblock %} 
     {% block content %} 
     {% if "query" in request.GET %} 
      <h1>Posts containing "{{ cd.query }}"</h1> 
      <h3>Found {{ total_results }} result{{ total_results|pluralize}}</h3> 
      {% for result in results %} 
      {% with post=result.object %} 
       <h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4> 
       {{ post.body|truncatewords:5 }} 
      {% endwith %} 
    {% empty %} 
    <p>There are no results for your query.</p> 
      {% endfor %} 
      <p><a href="{% url 'blog:post_search' %}">Search again</a></p> 
     {% else %} 
      <h1>Search for posts</h1> 
      <form action="." method="get"> 
      {{ form.as_p }} 
      <input type="submit" value="Search"> 
      </form> 
     {% endif %} 
     {% endblock %} 

Antwort

3

Wenn es nicht query GET-Parameter übergeben, oder die Form passieren würde nicht Validierung wäre - in diesem Fall total_results und results nicht definiert werden würde . Sie müssen entweder die Standardwerte für den Fall vorsehen, z.B .:

def post_search(request): 
    results = [] 
    total_results = 0 

    form = SearchForm() 
    if 'query' in request.GET: 
     form = SearchForm(request.GET) 
     if form.is_valid(): 
      cd = form.cleaned_data 
      results = SearchQuerySet().models(Post)\ 
       .filter(content=cd['query']).load_all() 
      # count total results 
      total_results = results.count() 
    template = 'blog/post/search.html' 
    context = { 
     'form': form, 
     'cd': cd, 
     'results': results, 
     'total_results': total_results 
    } 
    return render(request, template, context) 

Oder eine bestimmte „Validierung“ Fehler im Fall werfen gibt es keine query Parameter oder Formular ist ungültig.

+0

Die Art, wie Sie es oben haben, adressiert cd nicht, also tat ich cd = []. dann, wenn ich versuche zu suchen, bekomme ich diese Nachricht 'NoneType' Objekt hat kein Attribut '_default_manager' – losee

+0

@lose guten Punkt. Lassen Sie uns zuerst einigen, was Sie tun möchten, wenn das Formular die Validierung nicht besteht - einen Fehler werfen? .. danke. – alecxe

3
def post_search(request): 
    results = [] # or None 
    total_results = 0 # or None 
    form = SearchForm(request.GET or None) 
    if 'query' in request.GET: 

     if form.is_valid(): 
      cd = form.cleaned_data 
      results = SearchQuerySet().models(Post)\ 
       .filter(content=cd['query']).load_all() 
      # count total results 
      total_results = results.count() 
      template = 'blog/post/search.html' 
      context = { 
       'form': form, 
       'cd': cd, 
       'results': results, 
       'total_results': total_results 
        } 
       return render(request, template, context) 
     else: 
      return render(request, 'blog/post/search.html', {'form': form,}) 
    else: 
     return render(request, 'blog/post/search.html', {'form': form,}) 

Python ist unter Hinweis darauf, dass das, was passieren wird, wenn die ‚wenn‘ Zustand ausfällt, und nach wie vor verwenden Sie die Variable ‚TOTAL_RESULTS‘ im Kontext. Daher initialisiere es als 0 oder none wie du willst. Ähnlich wie bei der Variablen 'results'.

EDIT1: Da ich nicht genau weiß, was Sie erreichen wollen, würde ich am besten meinen Code verwenden.

EDIT2: Template Code ändert

{% extends "blog/base.html" %} 
    {% block title %}Search{% endblock %} 
    {% block content %} 
    {% if results %} 
     <h1>Posts containing "{{ cd.query }}"</h1> 
     <h3>Found {{ total_results }} result{{ total_results|pluralize}}</h3> 
     {% for result in results %} 
     {% with post=result.object %} 
      <h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4> 
      {{ post.body|truncatewords:5 }} 
     {% endwith %} 
{% empty %} 

<p>There are no results for your query.</p> 
     {% endfor %} 

     <p><a href="{% url 'blog:post_search' %}">Search again</a></p> 
    {% else %} 
     <h1>Search for posts</h1> 
     <form action="." method="get"> 
     {{ form.as_p }} 
     <input type="submit" value="Search"> 
     </form> 
    {% endif %} 
    {% endblock %} 
+0

Die Art, wie Sie es oben haben, adressiert nicht cd, also habe ich cd = []. dann, wenn ich versuche zu suchen bekomme ich diese Nachricht 'NoneType' Objekt hat kein Attribut '_default_manager' – losee

+0

Was genau machen Sie mit diesen Variablen in der Vorlage. Bitte poste den Code. – RA123

+0

Ich bearbeitet es siehe oben – losee

1

ich durch das gleiche Buch gegangen sind, und bemerkte das gleiche Problem mit diesem besonderen Blick. Hier war meine Lösung in der Ansicht. Ich verließ die Vorlage so, wie es (im Buch) war:

def post_search(request): 
    if 'query' in request.GET: 
     form = SearchForm(request.GET) 
     if form.is_valid(): 
      cd = form.cleaned_data 
      results = SearchQuerySet().models(Post).filter(content=cd['query']).load_all() 
      total_results = results.count() 
      context = {'form':form, 'cd':cd, 'results':results, 'total_results':total_results} 
      return render (request, 'blog/post/search.html', context) 
    else: 
     form = SearchForm() 
     context = {'form':form} 
     return render (request, 'blog/post/search.html', context) 
1

hatte genau das gleiche Problem ... der Code unten arbeitet

def post_search(request): 
     results = [] 
     total_results = 0 
     cd = None 
     form = SearchForm() 
     if 'query' in request.GET: 
      form = SearchForm(request.GET) 
      if form.is_valid(): 
      cd = form.cleaned_data 
      results = SearchQuerySet().models(Post).filter(content=cd['query']).load_all()  
     total_results = results.count() 
    return render(request, 'search/search.html', {'form':form, 
               'cd':cd, 
               'results':results, 
               'total_results':total_results, 
               }) 

Aber aus Interesse haben Sie auch feststellen, dass die post_detail view erzeugte ähnliche Fehler ?? gelöst das mit dieser Version des Codes

def post_detail(request, year, month, day, post): 


     post = get_object_or_404(Post, slug=post, 
            status='published', 
            publish__year=year, 
            publish__month=month, 
            publish__day=day) 


    #list of active comments for this post 
    comments = post.comments.filter(active=True) 

    if request.method == 'POST': 
     # A comment was posted 
     comment_form = CommentForm(data=request.POST) 
     if comment_form.is_valid(): 
      #create comment object but don't save to DB 
      new_comment = comment_form.save(commit=False) 
      # assitgn comment to post 
      new_comment.post = post 
      # save the comment to the DB 
      new_comment.save() 

    else: 
     comment_form =CommentForm() 





    post_tags_ids = post.tags.values_list('id', flat=True) 
    similar_posts = Post.published.filter(tags__in=post_tags_ids).exclude(id=post.id) 
    similar_posts = similar_posts.annotate(same_tags=Count('tags')).order_by('-same_tags','-publish')[:4] 


    args = {} 
    args['post'] = post 
    args['comment_form']= comment_form 
    args['comments'] = comments 
    args['similar_posts'] = similar_posts 
    return render(request, 'detail.html', args) 
Verwandte Themen