flask_admin - How can we filter selectable values in a form drop down? - flask-admin

I have a form with a select box. How can i put a filter so that only specific objects are shown?
class XYZ(ModelView):
column_list = ['id', 'selection']
I want to put a filter so that while creating/updating only those selection objects are shown that satisfy a particular predicate.

try
class XYZ(ModelView):
column_list = ['id', 'selection']
column_filters = ['selection']
Or for possibly more custom SQL from thedocs. http://flask-admin.readthedocs.org/en/latest/api/mod_contrib_sqla/
from flask_admin.contrib.sqla.filters import BaseSQLAFilter
class FilterLastNameBrown(BaseSQLAFilter):
def apply(self, query, value, alias=None):
if value == '1':
return query.filter(self.column == "Brown")
else:
return query.filter(self.column != "Brown")
def operation(self):
return 'is Brown'
class MyModelView(BaseModelView):
column_filters = [
FilterLastNameBrown(
User.last_name, 'Last Name', options=(('1', 'Yes'), ('0', 'No'))
)
]

Related

How can I gather and show results of a survey made with survey_kit package in Flutter?

I am struggling in retrieving the results obtained from a survey built with survey_kit package. A SurveyResult object is supposed to contain a list of StepResults and the FinishReason. The StepResult contains a list of QuestionResults. I cannot access the StepResult in anyway.
Example proposed in the documentation:
SurveyKit
(
onResult: (SurveyResult result) {
//Read finish reason from result (result.finishReason)
//and evaluate the results }
)
I already tried to tap something like result.stepResult but no variable was suggested.
I'm not sure if its the best approach but after looking into SurveyKit I've found that the SurveyResult class holds a list of StepResult and each of them holds a list of QuestionResult which in turn holds a value field called valueIdentifier.
so you can Iterate over them and extract the values. but first, you need to ensure that all of your answers have value. for example:
answerFormat: const SingleChoiceAnswerFormat(
textChoices: [
TextChoice(text: 'option 1', value: '10'),
TextChoice(text: 'option 2', value: '-2'),
]
),
Then after you did that iterate over them like that:
onResult: (SurveyResult result) {
int score = 0;
for (var stepResult in result.results) {
for (var questionResultin stepResult.results) {
score += int.tryParse(questionResult.valueIdentifier ?? "0") ?? 0;
}
}
print("final Score is $score");
/* call a new widget to show the results*/
},
As you can see I use two null checks when adding a question value to the score.
The first one is because the value is of type "String?" (and not "String") and the second one is because the String value might be non-numeric.
Of course, after you have calculated the results you can show the result on a new screen with Navigator.

Why is my dynamic sql resulting in the error shown below?

I am trying to build a sql statement dynamically and this is one variation of the result.
sqlQuery {
name: 'fetch-products',
text: 'select * from products where category =
$1 and designer in $2',
values: [ 'WOMENSCLOTHING', "('Adjavon', 'ALC', 'Adele', 'Bagley')" ]
}
I build the sql with the following code segment:
const {
category,
designers,
} = JSON.parse(filters);
let values = [category];
let text = 'select * from products where category = $1';
if(designers) {
text = text + ' and designer in $2';
values.push(designers);
}
I execute it in the following segment:
try {
const allProducts = await pool.query(sqlQuery);
res.status(200).json(allProducts.rows);
} catch (error) {
console.error(error);
return res.status(500).send('Problems gettting products by category.')
}
And get the following error:
error: syntax error at or near "$2"
I am thinking the error may be the double quotes placed around designer when it is pushed on the values array:
values: [ 'WOMENSCLOTHING', "('Adjavon', 'ALC', 'Adele', 'Bagley')" ]
I don't know what library you are using exactly, but the values property looks highly suspicious.
sqlQuery {
name: 'fetch-products',
text: 'select * from products where category =
$1 and designer in $2',
values: [ 'WOMENSCLOTHING', "('Adjavon', 'ALC', 'Adele', 'Bagley')" ]
}
If your drivr/library supports this, the second element in the array should be an actual array and not a string like '("foo", "bat")'. How is the driver supposed to know this is meant as a list and not a single string that has this value?
I guess in a nutshell you have to bring the query in this form:
const query = 'select * from products where category = $1 and designer in ($2, $3, $4, $5)'
const values = [ 'WOMENSCLOTHING', 'Adjavon', 'ALC', 'Adele', 'Bagley' ]
That requires some extra work on the backend to map the values and bring them into the right shape.
I guess you could get that done with something like this:
const category = 'icecream'
const designers = ['jim', 'maria']
let values = [category];
let text = 'select * from products where category = $1';
if (designers) {
text += ` and designer in (${designers.map((d, i) => `$${i+2}`).join(', ')})`;
values = [...values, ...designers];
}
console.log(text);
console.log(values);

Skip inserting data in the list

I've got getter which gets list of my FilterModelRow. If condition is null I want to skip inserting the data into the list and the best do it inline
get getFilterRows {
return [FilterRowModel(Icon(Icons.title), 'Age', 'equal', age),
FilterRowModel(Icon(Icons.title), 'Age', 'min', minAge),
FilterRowModel(Icon(Icons.title), 'Age', 'max', maxAge)
];
}
I tried
...
age != null FilterRowModel(Icon(Icons.title), 'Age', 'equal', age): null
...
But that insert null which ends with an error. So how to completely skip adding line into the list if condition is met
Simplified version
var age = null;
List<int> myList = [age!=null ? age : null];
print(myList); //--> return [null] and I want to return empty list []
If you tell to your list to insert a null value, it will.
Now you have two options :
1 - You can instantiate your list and add values that are not null
List<int> myList = [];
if (age != null) myList.add(age);
2 - You can remove null values from your list with removeWhere method
myList.removeWhere((value) => value == null);

OrientDB: filter by entire embedded field value

I'm to insert a record with embedded field in OrientDB and then to query for that record using filter:
insert into MyClass set embeddedField = {'#type': 'd', 'id': 1}
works well, and
select from MyClass
returns the record I've added. But when I add where with filter for embeddedField, I get no results:
select from MyClass where embdeddedField = {'#type': 'd', 'id': 1}
I thought that it could happen because Orient adds #version field into embedded document, so I tried to search with version:
select from MyClass where embdeddedField = {'#type': 'd', '#version': 0, 'id': 1}
But still got no results.
Question: Any idea how to filter embedded field by entire document? Without the need to filter explicitly by each field of embedded document:
select from MyClass
where embdeddedField.id = 1
and embdeddedField.field2 = val2
and embeddedField.field3 = val3
Because for several reasons I would like to pass the entire object as single query parameter:
select from MyClass where embdeddedField = ?
Thats because the provided Hash is transformed to an embedded class.
Perhaps take a look at the ActiveOrientWiki https://github.com/topofocus/active-orient/wiki/Relations
To explain:
Take a class base, there a document with two properties (schemaless)
and add existing documents to it
( 0..9 ).each do | b |
base_record= Base.create label: b, first_list: []
( 0..9 ).each {|c| base_record.first_list << FirstList.create( label: c ) }
end
INFO->CREATE VERTEX base CONTENT {"label":0,"first_list":[]}
INFO->CREATE VERTEX first_list CONTENT {"label":0}
INFO->update #136:0 set first_list = first_list || [#147:0] return after #this
then links are embedded and the record looks like
=> #<Base:0x00000000041a60e0 #metadata={:type=>"d", :class=>"base", :version=>11, :fieldTypes=>"first_list=z", :cluster=>129, :record=>1},
#attributes={:first_list=>["#149:1", "#150:1", "#151:1", "#152:1", "#145:2", "#146:2", "#147:2", "#148:2", "#149:2", "#150:2"], :label=>"1"}>
if you expand the list items, you can query for "#type"
If you add a document without rid, the same thing happens
( 0..9 ).each {|c| base_record.first_list << FirstList.new( label: c ) }
20.04.(12:53:59) INFO->update #130:2 set first_list = first_list || [{ #type: 'd' ,#class: 'first_list' ,label: 0 }] return after #this
INFO->CREATE VERTEX base CONTENT {"label":"c","first_list":[]}
'#130:2'.expand
=> #<Base:0x00000000043927a0 #metadata={:type=>"d", :class=>"base", :version=>11, :fieldTypes=>"first_list=z", :cluster=>130, :record=>2},
#attributes={:first_list=>["#151:12", "#152:12", "#145:13", "#146:13", "#147:13", "#148:13", "#149:13", "#150:13", "#151:13", "#152:13"], :label=>"c"}>
If you omit the class-name, only the scope of the rid's changes
INFO-> update #132:2 set first_list = first_list || { #type: 'd' ,label: 0 } return after #this
=> [#<Base:0x0000000003a26fb8 #metadata={:type=>"d", :class=>"base", :version=>3, :fieldTypes=>"first_list=z", :cluster=>132, :record=>2},
#attributes={:first_list=>["#3:0"], :label=>"d"}>]
In any case, a query for #type failes

In Scala, how do I return a list of all object instances with a property set to a certain value

I am using Scala, and would like to be able to select all instances of an object with a property set to a given value. Say I have an Order class and a Order Item class, and I want to select or pull all of the order items with an order id of say 1, and return all of these in a list, how do I do this?
I would like to be able to return a list of order line items that have an order id of say 1
Here is my Line Item class definition:
Code:
case class LineItem(val itemId : Int, val orderId:Int, val productId:Int, val quantity:Int)
I then have some order items defined in an object:
Code:
object LineItem {
val li1 = new LineItem(1, 1, 1, 10)
val li2 = new LineItem(2, 1, 4, 1)
val li3 = new LineItem(3, 1, 2, 1)
val li4 = new LineItem(4, 1, 3, 1)
val li5 = new LineItem(5, 2, 1, 1)
val li6 = new LineItem(6, 1, 7, 1)
var lineItems = Set(li1, li2, li3, li4, li5, li6)
def findItemsInOrder(ordId:Int) = lineItems.find(_.orderId == ordId)
}
As you can see 5 of the line items belong to the order with an id of 1.
So first a list of orders are printed out for the user to see, then I want the user to be able to select an order to see all the line items within that order, so I would like these line items to be printed out in the shell.
So the order id is inputted by the user:
Code:
val orderNo = readLine("Which order would you like to view?").toInt
And then this line:
Code:
println("OrderID: " + LineItem.findItemsInOrder(orderNo).get.orderId + ", ProductID: " + LineItem.findItemsInOrder(orderNo).get.productId + ", Quantity: " + LineItem.findItemsInOrder(orderNo).get.quantity)
Only prints out the first line item with an order id of 1.
I have then tried to loop through all line items, like this:
Code:
var currentLineItems = new ListBuffer[LineItem]()
for (item <- LineItem.lineItems){
val item1: LineItem = LineItem(LineItem.findItemsInOrder(orderNo).get.lineId, LineItem.findItemsInOrder(orderNo).get.orderId, LineItem.findItemsInOrder(orderNo).get.productId, LineItem.findItemsInOrder(orderNo).get.quantity)
currentLineItems += item1
}
for (item <- currentLineItems ){
println("OrderID: " + LineItem.findItemsInOrder(orderNo).get.orderId + ", ProductID: " + LineItem.findItemsInOrder(orderNo).get.productId + ", Quantity: " + LineItem.findItemsInOrder(orderNo).get.quantity)
}
But this code just prints out the same line item 6 times.
I would be very grateful for any help received to help solve my problem
Thanks
Jackie
Define findItemsInOrder to filter out all elements in the list that match the order id:
def findItemsInOrder(ordId: Int): List[LineItem] = lineItems.filter(_.orderId == ordId)
find will locate the first element matching the id, if found will return Some[T] where T is the element type, else None:
Finds the first element of the sequence satisfying a predicate, if any.
If you have multiple elements which match against the id, you need filter:
Selects all elements of this traversable collection which satisfy a predicate.