我很难保留存储在 Django JSONField 中的 JSON 对象中的键顺序。我已尝试按照文档使用自定义编码器和解码器,但 JSON 对象不断重新排序自身:
>>>from models import MyModel
>>>my_dict = {"c": 3, "b": 2, "a": 1}
>>>my_model = MyModel()
>>>my_model.my_field = my_dict
>>>my_model.save()
>>>my_model.refresh_from_db()
>>>my_model.my_field
OrderedDict([('a',1), ('b', 2), ('c', 3)])
Run Code Online (Sandbox Code Playgroud)
我原以为它会回来OrderedDict([('c',3), ('b', 2), ('a', 1)])。
这是我到目前为止所尝试过的:
模型.py:
import collections
import json
from django.db import models
class OrderedEncoder(json.JSONEncoder):
def encode(self, o):
if isinstance(o, collections.OrderedDict):
encoded_objs = [
f"{self.encode(k)}: {self.encode(v)}"
for k, v in o.items()
]
return f"{{{','.join(encoded_objs)}}}"
else:
return super().encode(o)
class OrderedDecoder(json.JSONDecoder):
def __init__(self, …Run Code Online (Sandbox Code Playgroud) 我想用 JSONEncoder 将字典编码为 json。它看起来像一个请求,接收一个字典作为参数并将其编码为 json 作为 http 正文。代码如下所示:
let dict = ["name": "abcde"]
protocol Request {
var params: [String: Encodable] { get set }
func encode<T>(_ value: T) throws -> Data where T : Encodable
}
extension Request {
func encode<T>(_ value: T) throws -> Data where T : Encodable {
return try JSONEncoder().encode(value)
}
var body: Data? {
if let encoded = try? self.encode(self.params) {
return encoded
}
return nil
}
}
struct BaseRequest: Request {
var params: [String …Run Code Online (Sandbox Code Playgroud) struct TestEnc: Codable {
var date = Date()
}
let encoder = JSONEncoder()
let tenc = TestEnc()
let jsonData = try encoder.encode(tenc)
let json = String(data: jsonData, encoding: String.Encoding.utf8)
print("json:\(json)")
Run Code Online (Sandbox Code Playgroud)
这打印:
json:Optional("{\"date\":589331953.61679399}")
Run Code Online (Sandbox Code Playgroud)
我在文档中找不到这应该代表什么。
let encoder = JSONEncoder()
do {
let encodData = try encoder.encode("test string") // same as Int type
print(encodData) // nil
} catch let err {
print(err.localizedDescription) // The data couldn’t be written because it isn’t in the correct format.
}
Run Code Online (Sandbox Code Playgroud)
如何编码这些类型值
我正在尝试使用Swift 4的Encodable + JSONEncoder将结构序列化为String.该对象可以保存异类值,如String,Array,Date,Int等.
使用的方法可以正常工作,但Date除外.JSONEncoder的dateEncodingStrategy属性没有任何影响.
这是一个片段,它重现了Playground中的行为:
struct EncodableValue:Encodable {
var value: Encodable
init(_ value: Encodable) {
self.value = value
}
func encode(to encoder: Encoder) throws {
try value.encode(to: encoder)
}
}
struct Bar: Encodable, CustomStringConvertible {
let key: String?
let value: EncodableValue?
var description: String {
let encoder = JSONEncoder()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "E, d MMM yyyy"
dateFormatter.locale = Locale(identifier: "en_US_POSIX")
encoder.dateEncodingStrategy = .formatted(dateFormatter)
let jsonData = try? encoder.encode(self)
return String(data: jsonData!, encoding: .utf8)!
} …Run Code Online (Sandbox Code Playgroud) 我只是很好奇如何将具有String键和Encodable值的字典编码为JSON。
例如:
let dict: [String: Encodable] = [
"Int": 1,
"Double": 3.14,
"Bool": false,
"String": "test"
]
Run Code Online (Sandbox Code Playgroud)
其中的键dict都是type String,但是值的类型各不相同。
但是,JSON中允许所有这些类型。
我想知道JSONEncoder在Swift 4中是否有一种方法可以将其编码dict为JSON Data。
我确实知道还有其他方法无法使用JSONEncoder,但是我只是想知道是否JSONEncoder有能力进行管理。
将Dictionary确实有func encode(to encoder: Encoder) throws在扩展,但仅适用于约束Key: Encodable, Key: Hashable, Value: Encodable,而对于我们dict,它需要约束Key: Encodable, Key: Hashable, Value == Encodable。
struct为此拥有一个就足够了JSONEncoder,
struct Test: Encodable {
let int = 1
let double …Run Code Online (Sandbox Code Playgroud) jsonencoder ×6
swift ×4
encodable ×3
codable ×2
dictionary ×1
django ×1
ios ×1
json ×1
jsondecoder ×1
swift4 ×1