简体   繁体   中英

Django object not iterable, why?

I want display username if he click on i want join button using ajax. I have html that look like this :

    <div class="who_come">
       <form class="form-inline" role="form" method="post" id="joinToEventForm">
      {% csrf_token %}
      <p align="left"><b ><button type="submit">I want join</button></b></p></b></p>
       </form>
       {% for u in who_come %}
       <p><a href="profile/{{u.visiter}}">{{u.visiter}}</a></p>
       {% endfor %}
    </div>

i use this code to produce my ajax :

$('#joinToEventForm').on('submit', function(event){
    event.preventDefault();
    console.log("form submitted!")  // sanity check

   $.ajax({
       type:'POST',
       data:{
           csrfmiddlewaretoken:'{{ csrf_token }}'
       },
       success : function () {
           alert("You are on Envent")
       }
   });
});

it code works, and write to database what i need, but it return to me 500 error code with TypeError: 'WhoComeOnEvent' object is not iterable . I can't understand what is a problem

it is my model:

class WhoComeOnEvent(models.Model):
   visiter = models.ForeignKey(User, related_name='WhoComeOnEvent')
   which_event = models.ForeignKey(Topic, related_name='WhoComeOnEvent')

    def __str__(self):
        return '%s go to %s' % (self.visiter.username, self.which_event.subject)

it is my view :

def p(request, pk):
    user = request.user
    topic = get_object_or_404(Topic, pk=pk)
    post = get_object_or_404(Post, pk=pk)
    comment = Comments.objects.filter(pk=pk)
    who_come = WhoComeOnEvent.objects.filter(pk=pk)
    if request.is_ajax():
        who_come = WhoComeOnEvent.objects.create(
            visiter=user,
            which_event=post.topic

        )

    if request.method == 'POST':
        form = CustomCommentForm(request.POST)
        if form.is_valid():
            comment = form.save(commit=False)
            comment.post = post
            comment.creator = user
            comment.save()
            comment = Comments.objects.create(
                body=form.cleaned_data.get('body'),
                creator=user,

            )
            return render(request, 'post.html', {'post': post, 'topic': topic, 'comment': comment,
                                                 'form': form, 'who_come': who_come})
    else:
        form = CustomCommentForm()
    return render(request, 'post.html', {'post': post, 'topic': topic, 'comment': comment,
                                         'form': form, 'who_come': who_come})

I use WhoComeOnEvent.objects.filter , as far as i know it may be iterable. I was try use __iter__ and it doesn't help me. I was try use object.filter(...).values() , but it too do not help. I think may be i made wrong logic in ajax functionality. Please don't be mad if it stupid question, i use ajax first time at my life.

Edit

I solved 500 error and iterable problem by replacing

{% for u in who_come %}
 <p><a href="profile/{{u.visiter}}">{{u.visiter}}</a></p>
{% endfor %}

to

{% for u in who_come.visiter.all %}
 <p><a href="profile/{{u.username}}">{{u.username}}</a></p>
{% endfor %}

but it not display link on user in html

If you see, if this condition is true:

if request.is_ajax()

then who_come is going to be a WhoComeOnEvent.objects.create object and that's not an iterable!

You need to send back something useful to change the HTML after the AJAX call.

Solution :

from django.http import HttpResponse

def p(request, pk):
    # your existing code
    if request.is_ajax():
        # change variable name
        who_come_obj = # same create code

        visitors_usernames = []
        for w in who_come:
            visitors_usernames.append(w.visiter.username)

        return HttpResponse(json.dumps(visitors_usernames)) 

In Javascript AJAX success method:

$.ajax({
  ...
  success: function(data) {
    //seems more useful try to use convertation
    var to_json = JSON.stringify(data);
    var usernames = JSON.parse(to_json);
    var html_str = '';

    for (var i=0; i < usernames.length; i++) {
      html_str += '<p><a href="profile/' + usernames[i] + '">' + usernames[i] + '</a></p>';
    }

    $('#who_come_links').html(html_str);
  }
});

Finally, wrap the links with a div with id who_come_links in HTML

<div id="who_come_links">
  {% for u in who_come %}
    <p><a href="profile/{{u.visiter.username}}">{{u.visiter.username}}</a></p>
  {% endfor %}
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM