I have a slug ArrayField on a model.
How can I filter or get by the entire exact array only?
I'm currently doing something like this:
search = f'["a", "b", "c"]'
list = search[2:-2].split("', '")
dict = {}
for n, item in enumerate(list):
dict[f"slug__{n}"] = item
obj = queryset.filter(**dict)
However, this returns any object where the slug begins with "a", "b", and "c".
E.g.
["a", "b", "c"]
["a", "b", "c", "d"]
["a", "b", "c", "d", "e"]
["a", "b", "c", "123"]
How do I do a filter or get so that only the entire and exact slug match returns? I.e. obj only returns objects with a slug of ["a", "b", "c"]
To filter an ArrayField by an exact match you can just pass the list to match against to a filter
queryset = queryset.filter(slug=["a", "b", "c"])
I have some code in the general form:
variable "foo" {
type = "list"
default = [ 1,2,3 ]
}
resource "bar_type" "bar" {
bar_field = "${var.foo}"
}
I want to append an addition value to bar_field without modifying foo. How can I do this? I don't see any sort of contacting or appending functions in their docs.
This is 0.11.x Terraform
You can use the concat function for this. Expanding upon the example in your question:
variable "foo" {
type = "list"
default = [ 1,2,3 ]
}
# assume a value of 4 of type number is the additional value to be appended
resource "bar_type" "bar" {
bar_field = "${concat(var.foo, [4])}"
}
which appends to the value assigned to bar_field while ensuring var.foo remains unchanged.
Adding new item to the list if not present:
locals {
oldlist = ["a", "b", "c"]
newitem = "d"
newlist = (contains(local.oldlist, local.newitem) == false ? concat(local.oldlist, [local.newitem]) : local.oldlist)
}
output "newlist" {
value = local.newlist
}
var1 = ["string1","string2"]
var2 = "string3"
var3 = concat(var1, formatlist(var2))
If I have:
class Tag(models.Model):
number = models.IntegerField()
config = {
"data": 1,
"field": "number"
}
How do I do the following?
record = Tag(config["field"]=config["data"])
record.save()
You can unpack dict to arguments using this syntax **. For example:
config = {
"number": 1
}
record = Tag(**config)
record.save()
This will create new tag instance with number=1 value.
The following iOS code ("object" type with "og.likes" action) works just fine:
let properties = [
"og:type": "object",
"og:title": "Test Product",
"og:description": "Product description"
]
let object = FBSDKShareOpenGraphObject(properties: properties)
let action = FBSDKShareOpenGraphAction()
action.actionType = "og.likes"
action.setObject(object, forKey: "object")
let content = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "object"
FBSDKShareDialog.show(from: self, with: content, delegate: nil)
However, I prefer using "product" type rather than the generic "object" type. The following code is the same as the above one only replacing "object" with "product" (so this time trying to post a story about "product" type with "og.likes" action)
let properties = [
"og:type": "product",
"og:title": "Test Product",
"og:description": "Product description"
]
let object = FBSDKShareOpenGraphObject(properties: properties)
let action = FBSDKShareOpenGraphAction()
action.actionType = "og.likes"
action.setObject(object, forKey: "product")
let content = FBSDKShareOpenGraphContent()
content.action = action
content.previewPropertyName = "product"
FBSDKShareDialog.show(from: self, with: content, delegate: nil)
This code generated the following error:
Action Requires At Least One Reference: The action you’re trying to
publish is invalid because it does not specify any reference objects.
At least one of the following properties must be specified: object.
Any idea why?
I'm new in swift. I'm trying to add an Array to a specific key in my Dictionary.
I have the following code:
var myArray : Array<Links> = []
var myDict : Dictionary<String, AnyObject> = [:]
myDict["links"] = myArray as AnyObject? // I need help in this row, It does not work.
This is the Json structure I have in myDict and I'm trying to set:
id : "blabla"
links: [
0: {key1: "a", key2: "b", name: "c", link: "d"}
1: {key1: "e", key2: "f", name: "j", link: "h"}
]
Please, consider I already have all the rest working properly. My only problem is how to add my array in the dictionary as commented in the code above.
My JSON structure:
I hope I could make myself clear enough.
Thank you.
First of all don't cast types up and don't annotate types unless the compiler complains.
Second of all a JSON dictionary is [String:Any] in Swift 3.
Further the recommended syntax to create an empty collection object is
var myDict = Dictionary<String, Any>()
Assuming your array – actually a dictionary – is
let myArray = [
0: ["key1": "a", "key2": "b", "name": "c", "link": "d"],
1: ["key1": "e", "key2": "f", "name": "j", "link": "h"]
]
just assign it:
myDict["links"] = myArray
Even if there is a struct
struct Link {
var key1, key2, name, link : String
}
and the array dictionary is
let linkDictionary = [
0: Link(key1:"a", key2: "b", name: "c", link: "d"),
1: Link(key1:"e", key2: "f", name: "g", link: "h")]
you can assign it if the value type is Any
myDict["links"] = linkDictionary
Assuming, for a second, that links really was an array, it would be:
var dictionary: [String: Any] = [
"id": "blabla",
"links": [
["key1": "a", "key2": "b", "name": "c", "link": "d"],
["key1": "e", "key2": "f", "name": "j", "link": "h"]
]
]
// retrieve links, or initialize it if not found
var links = dictionary["links"] as? [[String: String]] ?? [[String: String]]()
// add your new link to local dictionary
links.append(["key1": "k", "key2": "l", "name": "m", "link": "n"])
// update original structure
dictionary["links"] = links
Personally, though, when I see a repeating dictionary structure like your links, this screams for a real model for these objects. For example:
struct Foo {
let id: String
var links: [Link]?
}
struct Link {
let key1: String
let key2: String
let name: String
let link: String
}
var foo = Foo(id: "blabla", links: [
Link(key1: "a", key2: "b", name: "c", link: "d"),
Link(key1: "e", key2: "f", name: "j", link: "h")
])
foo.links?.append(Link(key1: "k", key2: "l", name: "m", link: "n"))
Now, in this latter example, I assumed that links was really an array, not a dictionary, but that's not really my point here. My key observation is that code is more readable and robust if you use proper custom types rather than just arrays and dictionaries.
And if you need to send and receive these model objects to some web service, you then map this model object to and from JSON. But use custom types for your actual model.
If you want to make the above types easily converted to and from JSON, you can use one of the object mapping libraries out there, so you can do something yourself, e.g.:
protocol Jsonable {
var jsonObject: Any { get }
init?(jsonObject: Any)
}
extension Foo: Jsonable {
var jsonObject: Any {
return [
"id": id,
"links": links?.map { $0.jsonObject } ?? [Any]()
]
}
init?(jsonObject: Any) {
guard let dictionary = jsonObject as? [String: Any],
let id = dictionary["id"] as? String else { return nil }
var links: [Link]?
if let linksDictionary = dictionary["links"] as? [Any] {
links = linksDictionary.map { Link(jsonObject: $0)! }
}
self.init(id: id, links: links)
}
}
extension Link: Jsonable {
var jsonObject: Any { return [ "key1": key1, "key2": key2, "name": name, "link": link ] }
init?(jsonObject: Any) {
guard let dictionary = jsonObject as? [String: Any],
let key1 = dictionary["key1"] as? String,
let key2 = dictionary["key2"] as? String,
let name = dictionary["name"] as? String,
let link = dictionary["link"] as? String else {
return nil
}
self.init(key1: key1, key2: key2, name: name, link: link)
}
}
Then you can do stuff like:
let object = try JSONSerialization.jsonObject(with: data)
var foo = Foo(jsonObject: object)!
Or:
foo.links?.append(Link(key1: "j", key2: "k", name: "l", link: "m"))
let data = try! JSONSerialization.data(withJSONObject: foo.jsonObject)
This was the solution:
var arrLinks : Array<Dictionary<String, Any>> = []
for link in myArray {
var dict : Dictionary<String, Any> = [:]
dict["key1"] = link.name
dict["key2"] = link.ghostBefore
dict["key3"] = link.ghostAfter
arrLinks.append(dict)
}
myDict["links"] = arrLinks as AnyObject