使用Java POST请求在Django Tastypie上创建资源但获取500错误代码

时间:2013-01-04 17:45:48

标签: java django json rest tastypie

我正在尝试使用Java客户端向django tastypie API发布新资源,但我收到了Http 500错误代码。 基本上我只是想从客户端对我的api进行新的预订。

型号:

class Author(models.Model):
    name = models.CharField(max_length=50)
    email = models.EmailField()

    def __unicode__(self):
        return self.name

class Product(models.Model):
    author = models.ForeignKey(Author)

    name = models.CharField(max_length=100)
    genre = models.CharField(max_length=100)
    pub_date = models.DateTimeField()

class Reservation(models.Model):
    user = models.ForeignKey(User)
    product = models.ForeignKey(Product)

    reserv_date_start = models.DateTimeField()
    reserv_finish = models.DateTimeField()
    penalty = models.BooleanField()

    def __unicode__(self):
        return self.product.name

资源:

class AuthorResource(ModelResource):
    #user = fields.ForeignKey(UserResource, 'user')
    class Meta:
        queryset = Author.objects.all()
        resource_name = 'author'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

class ProductResource(ModelResource):
    author = fields.ForeignKey(AuthorResource, 'author')
    class Meta:
        queryset = Product.objects.all()
        resource_name = 'product'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

class ReservationResource(ModelResource):
    product = fields.ForeignKey(ProductResource, 'product')
    class Meta:
        queryset = Reservation.objects.all()
        resource_name = 'reservation'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

我发布的json(我正在使用java简单的json,我得到反斜杠,我不知道如何把它拿出来):

public JSONObject encodeJsonObject(Reservation reservation){
    JSONObject obj=new JSONObject();
    obj.put("id",String.valueOf(reservation.getId()));
    obj.put("product","/api/reservation/product/"+reservation.getProduct().getId()+"/");      
    obj.put("reserv_date_start",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+00:00'").format(reservation.getReserv_date_start()));
    obj.put("reserv_finish",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+00:00'").format(reservation.getReserv_finish()));        
    obj.put("resource_uri", "/api/reservation/reservation/"+reservation.getId()+"/");
    obj.put("penalty",reservation.isPenalty());
    return obj;
}

json: {
"product": "\/api\/reservation\/product\/12\/",
"id": "7",
"reserv_finish": "2013-01-05T23:11:51+00:00",
"resource_uri": "\/api\/reservation\/reservation\/7\/",
"penalty": false,
"reserv_date_start": "2013-01-05T23:11:51+00:00"

}


我的客户发布代码:

public void apacheHttpClientPost(String url, String user, char[] pass, JSONObject data) {
     try {

    DefaultHttpClient httpClient = new DefaultHttpClient();
            httpClient.getCredentialsProvider().setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT, AuthScope.ANY_REALM),
            new UsernamePasswordCredentials(user, new String(pass)));
    HttpPost postRequest = new HttpPost(url);
    StringEntity input = new StringEntity(data.toJSONString());
    input.setContentType("application/json");
    postRequest.setEntity(input);

    HttpResponse response = httpClient.execute(postRequest);

    if (response.getStatusLine().getStatusCode() != 201) {
        throw new RuntimeException("Failed : HTTP error code : "
            + response.getStatusLine().getStatusCode());
    }

    BufferedReader br = new BufferedReader(
                    new InputStreamReader((response.getEntity().getContent())));

    String output;
    System.out.println("Output from Server .... \n");
    while ((output = br.readLine()) != null) {
        System.out.println(output);
    }

    httpClient.getConnectionManager().shutdown();

  } catch (MalformedURLException e) {

    e.printStackTrace();

  } catch (IOException e) {

    e.printStackTrace();

  }

}

其中一个调试错误:

  

/usr/local/lib/python2.7/dist-packages/django/db/models/fields/的初始化的.py:808:   RuntimeWarning:DateTimeField收到一个天真的日期时间(2013-01-04   17:31:57)虽然时区支持是活跃的。 RuntimeWarning)

我发帖到

  

“HTTP://本地主机:8000 / API /预订/预约/”

2 个答案:

答案 0 :(得分:1)

JSON中的日期时间缺少时区部分:

json: {
    "product": "\/api\/reservation\/product\/9\/",
    "id": "6",
    "reserv_finish": "2013-01-04T17:31:57",                 // <-- Here
    "resource_uri": "\/api\/reservation\/reservation\/6\/",
    "penalty": false,
    "reserv_date_start": "2013-01-04T17:31:57"              // <-- And here
}

ISO-8601日期时间应如下所示:

"2013-01-04T17:31:57+00:00"
                    ^^^^^^^

此外,您安装了哪个python-dateutil版本?你能来看看吗?

pip freeze | grep dateutil

值得关注的其他事项:

答案 1 :(得分:0)

得到了它。问题是我的json不完整。我有一个我没有添加的用户资源的外键。这是解决方案:

JSON:

{
    "product": "\/api\/reservation\/product\/12\/",
    "id": "7",
    "reserv_finish": "2013-01-06T15:26:15+00:00",
    "resource_uri": "\/api\/reservation\/reservation\/7\/",
    "penalty": false,
    "reserv_date_start": "2013-01-06T15:26:15+00:00",
    "user": "\/api\/reservation\/auth\/user\/1\/"
}

资源:

class ReservationResource(ModelResource):
    user = fields.ForeignKey(UserResource, 'user')
    product = fields.ForeignKey(ProductResource, 'product')
    class Meta:
        queryset = Reservation.objects.all()
        resource_name = 'reservation'
        authentication = BasicAuthentication()
        authorization = DjangoAuthorization()

java客户端代码:

public JSONObject encodeJsonObject(Reservation reservation){
    JSONObject obj=new JSONObject();
    obj.put("id",String.valueOf(reservation.getId()));  
    obj.put("product","/api/reservation/product/"+reservation.getProduct().getId()+"/");      
    obj.put("reserv_date_start",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+00:00'").format(reservation.getReserv_date_start()));
    obj.put("reserv_finish",new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'+00:00'").format(reservation.getReserv_finish()));        
    obj.put("resource_uri", "/api/reservation/reservation/"+reservation.getId()+"/");
    obj.put("user", "/api/reservation/auth/user/1/"); //not dynamic yet
    obj.put("penalty",reservation.isPenalty());
    return obj;
}