如何在django JSON中将用户ID替换为用户名?

时间:2012-01-28 15:11:56

标签: django json

我正在用ajax写一个简单的聊天,我遇到了JSON问题。我需要username而不是id

JSON似乎:

[{"pk": 41, "model": "chat.post", "fields": {"timestamp": "2012-01-27 22:14:46", "user": 1, "text": "weq"}}]`

我需要将"user": 1替换为"user": username

我怎么做?

我的模特:

    from django.db import models
    from django.contrib.auth.models import User

    class Post(models.Model):
        timestamp = models.DateTimeField(auto_now_add=True)
        text = models.TextField()
        user = models.ForeignKey(User)

        class Meta:
            ordering = ['-id']

        def __unicode__(self):
            return "[%s] %s by user: %s" % (
                self.timestamp.strftime("%Y-%m-%d %H:%M:%S"),
                self.text,
                self.user
            )

我的观点:

# -*- coding: utf-8 -*-
#!/usr/bin/env python
from django.http import HttpResponse
from django.core import serializers
from django.contrib.auth.decorators import login_required
from django.http import HttpResponseRedirect
from django.contrib.auth.decorators import login_required
from django.template import RequestContext
from django.shortcuts import render_to_response

from live.chat.models import Post

@login_required
def updates_after(request, id):
    response = HttpResponse()
    response['Content-Type'] = "text/javascript"
    response.write(serializers.serialize("json",
        Post.objects.filter(pk__gt=id)))
    # __gt - greaten then > id
    return response

@login_required
def saymessage(request):
    if request.method == 'POST':
        if "text" in request.POST:
            text = request.POST["text"]
            user = request.user
            message = Post()
            message.user, message.text = user, text
            message.save()
        return HttpResponseRedirect('/')
    else:
        pass

JSON响应示例: [   {     “pk”:42,     “model”:“chat.post”,     “fields”:{       “timestamp”:“2012-01-28 18:08:44”,       “用户”:1,       “text”:“dasd”     }   } ]

我的模板:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="utf-8" />

  <!-- Always force latest IE rendering engine (even in intranet) & Chrome Frame 
       Remove this if you use the .htaccess -->
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

  <title>templates</title>
  <meta name="description" content="" />
  <script type="text/javascript" language="javascript" src="/media/js/jquery.min.js"></script>
  <script type="text/javascript" language="javascript">
        function update() {
            update_holder = $("#update_holder");
            most_recent = update_holder.find("div:first");
            $.getJSON("/live/updates-after/" + most_recent.attr('id') + "/",
                function(data) {
                    cycle_class = most_recent.hasClass("odd") ? "even" : "odd";
                    jQuery.each(data, function(){
                        update_holder.prepend('<div id="' + this.pk
                            + '" class="update ' + cycle_class
                            + '"><div class="timestamp">'
                            + this.fields.timestamp
                + '</div><div class="user">'
                + this.fields.user
                            + '</div><div class="text">'
                            + this.fields.text
                            + '</div><div class="clear"></div></div>'
                        );
                        cycle_class = (cycle_class == "odd") ? "even" : "odd";
                    }); 
                }

        );
        }
        $(document).ready(function() {
            setInterval("update()", 10000);
        })
  </script>
  <link rel="stylesheet" type="text/css" href="/media/css/main.css" />
</head>
<body>
{% block content %}
  <div>
    <header>
      <h1>Live Update site</h1>
      <p>Содержимое обновляется автоматически</p>
    </header>
    {% if object_list %}
        <div id="update_holder">
            {% for object in object_list %}
                <div class="update {% cycle even,odd %}" id="{{ object.id }}">
                    <div class="timestamp">
                        {{ object.timestamp|date:"Y-m-d H:i:s" }}
                    </div>
          <div class="user">
          {{ object.user }}
          </div>
                    <div class="text">
                        {{ object.text|linebreaksbr }}
                    </div>
                    <div class="clear"></div>               
                </div>
            {% endfor %}
        </div>
    {% else %}
        <p>Нет обновлений</p>
    {% endif %}
  </div>
<form enctype="multipart/form-data" action="{% url chat.views.saymessage %}" method="post">{% csrf_token %}
Введите текст сообщения: <input type="text" name="text" id="text">
<input type="submit" name="submit" value="Отправить">
</form>
{% endblock %}
</body>
</html>

更新: 我发现了这个问题,我们需要使用natural_key(),并在用户管理器类中重载此方法,将下一个代码添加到models.py:

class UserManager(models.Manager):
    def unatural_key(self):
        return self.username
    User.natural_key = unatural_key

不要忘记将参数use_natural_keys=True添加到serializers.serialize()

2 个答案:

答案 0 :(得分:3)

您可能需要查看Natural Keys。自然键允许您指定序列化的外键字段。通过为用户构建主键,您可以在序列化中使用用户名,而不是ID。

答案 1 :(得分:0)

您应该将此方法更改为

def __unicode__(self):
    return "[%s] %s by user: %s" % (
            self.timestamp.strftime("%Y-%m-%d %H:%M:%S"),
            self.text,
            self.user.username
        )

但这是一个肮脏的解决方案。您的视图updates_after非常难看。我会更改updates_after。查看类似的view