Mezzanine BlogCategory parsing categories - mezzanine

I want to build a custom filter that takes a blog_post as an argument and does some parsing of the categories (attached to the blog post).
I tried like this:
from mezzanine import template
from mezzanine.blog.models import BlogPost, BlogCategory
register = template.Library()
#register.filter(name='has_friends')
def has_friends(blog_post):
categories = blog_post.categories.all()
if 'Friends' in categories:
return False
else:
return True
The problem is that blog_post.categories.all() returns something like this:
[<BlogCategory: Enemies>, <BlogCategory: Allies>, <BlogCategory: Friends>, <BlogCategory: Family>]
Questions:
how can I get the list of categories parsed like this ['Enemies', 'Allies', 'Friends', 'Family'] instead of above (in order for my if statement to work) ?
without the answer at above question 1, how can I use IF statement to search in the BlogCategory list shown above?
Thank you,
GG

Found the answer myself, this way: I used dir(category) to get its methods => found among: title, slug, etc...
then I use:
for category in categories:
if category.title == 'Friends':
# do stuff

Related

Strapi - How to GET data sorted based on relation property?

I have an Articles table and it has a relation with the Authors table. Each author has a name property. I want to make a GET request for the articles and receive the articles sorted based on their author's name.
When I use _sort=author in the url parameters, I get the articles sorted based on the author object's ID.
When I use _sort=author.name in the url parameters, I get the articles in a seemingly random order but definitely not based on author.name.
How can I get the data sorted based on author.name?
I use mongoDB as my database.
That is the default behavior of _sort. However, you can simply accomplish this by overriding the find method in api/article/services/article.js to sort by Author's name like so:
module.exports = {
async find(params, populate) {
let result = await strapi.query('article').find(params, populate);
if (params._sort == 'author')
return result.sort((a, b) => (a.author.name > b.author.name) ? 1 : -1);
return result;
},
}
Check the documentation for customizing services to get more info: https://strapi.io/documentation/v3.x/concepts/services.html#concept

Extbase "findBy" with multiple parameters

I got an extension in which i want to include some filters, i know figured out that i can filter the results that are shown of my listAction() by using findBy.
I tested it and it worked like this:
$cars = $this->carRepository->findByCarid("1");
$this->view->assign('cars', $cars);
My problem now is i need to filter the result with more than one Parameter, what if i want to add findByColor("blue") so it gives me all cars wit hid 1 and color blue? What solution does extbase have for that kind of search queries? i can`t find anything good or understandable in the documentation.
You have to extend you repository and code this functionality on your own. Extbase offers you a simple but powerful API to do so.
class whatEverYourRepositoryIsCalled extends \TYPO3\CMS\Extbase\Persistence\Repository {
public function findByFilter($carId, $color) {
// Create empty query = select * from table
$query = $this->createQuery();
// Add query options
return $query->matching(
// ALL conditions have to be met (AND)
$query->logicalAnd(
// table column carId must be euqal to $carId
$query->equals('carId', $carId),
// table column color must be euqal to $color
$query->equals('color', $color)
)
);
}
}
This is a quite simple approach to your problem. In a real world scenario I would probably use an array of filter criteria to do the filtering like array('carId' => 1, 'color' => 'blue'). Inside of findByFilter() those values would be extracted and added to the query.
The key is to build the desired query. A quite comprehensive explanation of how to do that can be found at http://blog.typoplanet.de/2010/01/27/the-repository-and-query-object-of-extbase/. Unfortunately it's not completely up to date but the part about constructing queries is still valid.

How to use array results from orientjs query in another query - array is not an "array"

I want to use an array-like result from a query, but am having trouble.
I have:
class case extends V
class doc extends V
class filedIn extends E
So, a document is filed in a class via an edge of class filedIn.
My first query pulls a set a vertices:
.select().from('case').one().then(function(result){...
I then want to select all the filedIn edges linking to any of those case vertices, but how?
JSON.stringify(result)
{"#type":"d","#class":"matter","title":"my case","in_filedIn":["#17:7","#17:8","#17:9"],"#rid":"#12:3","#version":12}
looks like result['in_filedIn'] is an array,
but
.select().from(result['in_filedIn']).all()
gets me this error from back from the database:
Error on parsing command at position #0: Error parsing query: \nSELECT * FROM [object Object]\nEncountered \
select().from('[#17:7,#17:8,#17:9]')
(hard coded) works.
.select.from("[" + ["#17:1","#17:2].join(',') + "]").all()
also works.
but
select.from("[" + result['in_filedIn'].join(,)+"]").all()
throws
result.in_filedIn.join is not a function
I.e. whatever kind of object it is, it's not inheriting from the Array prototype.
console.log(result['in_filedIn'])
produces:
Bag {
serialized: >'AQAAAAUAEQAAAAAAAAAHABEAAAAAAAAACAARAAAAAAAAAAkAEQAAAAAAAAAKABEAAAAAAAAADwAAAAA>AAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',
uuid: null,
_content:
[ { [String: '#17:7'] cluster: 17, position: 7 },
...
So I'm rather puzzled what to do.
I want to select all the edges whose #rid is listed in result.in_filedIn
Or have I misunderstood something?
Hi oliver in_filedIn is not an Array is a structure called RidBag in Orientjs the implementation is done in Bag.js.
If yo want to get the array you should do
result['in_filedIn'].all()
to get the array.
The following worked, though it's a bit dirty.
.from(JSON.stringify(result['in_filedIn']).replace(/"/g,""))
I'm still looking for a better answer!
I had a similar problem actually. When you instantiate your db connection, there's a config field they don't list in their docs called enableRIDBags.
So your config would look like:
{
host: 'localhost',
port: 2424,
username: 'blah',
password: 'blooh',
enableRIDBags: false
}
I find that it's better to just disable RIDBags as they're a bit finicky in node. The .all() trick listed above worked fine for me up until my vertices had more than 40 edges, as then they were all converted to SBTree bags instead of Embedded bags. If you check line 122 here, you'll see that they can't convert the trees to JSON when you call .all()

MongoID and multikey query problem

I have a model Item with an indexed field named _key, that is array of strings (keywords for search).
Now I need to do autocompletion for this model (through JSON) in another form, and the problem is that instead of exact search by all words input by user, I need to do exact search by all but one last word. So I made this scopes in this model:
scope :find_by_keywords, lambda { |keys| where(:_keys.all => keys) }
scope :for_autocomplete, lambda { |keys| where(:_keys.all => keys[0..-2], :_keys => /^#{keys[-1]}/i ) }
the first scope for exact search works well, but I have problems with second scope for autocomplete. MongoID optimises (or something like) this query, so it becomes
db_development['items'].find({:_keys=>/^qwer/i}, {})
i.e. it allways misses the first condition. It's not surprising, because it needs different criterias on field for different conditions.
So I have tried many-many options. Different combinations of .all and .in, separate to different 'wheres', 'all_in' method, 'find(:conditions => ...)' and so on. Could you please suggest, how I can do this job?
I've found such solution:
scope :for_autocomplete, lambda { |keys| where(:_keys.all => keys[0..-2]+ [ /^#{keys[-1]}/ ] ) }
Seems to be working.

one to many join - taking only the last one on the many part

I'm quite a newbie in EF, so I'm sorry if my question has been answered before.. I just can't figure out the syntax..
I have two entities, Category & Product, where one category has many products.
I want to get all categories, with only their latest product (it has a date property named timestamp)
I have no idea how to do that. :-/
If possible I'd like to know the syntax of the two ways to write it, both the sql-like syntax, and the C# like syntax, e.g.:
ctx.Categories.Include("Products").ToList()
from c in ctx.Categories.Include("Products")
Thanks!
Here's the SQL-like way:
var categories =
from p in products
group p by p.Category into g
select new { Category = g.TheKey, LatestProduct = g.Max(p => p.TimeStamp) };
This is the Lambda-way (warning, untested):
var categories = products.GroupBy(p => p.Category)
.Select(g => new { Category = g.TheKey,
LatestProduct = g.Max(p => p.TimeStamp)});
A note on Categories.Include("Products"), you don't need this in your example. You use "Include" for eager-loading, so that for example if you had a list of Categories returned from EF, when you do Categories.Product you will get the associated product.
But all you require is a list of categories, and a single product for each one - which is already returned in the above LINQ query, so no need for Include.