Django - how to make this query - django

I have the following model which is populated with something like this:
Property
concept_id name value
1 definition blablabla
1 prefLabel prefferedLabel
1 scope Scopeee
1 NOT_NEEDED a not needed value
2 definition another definition
2 prefLabel another label
2 scope another scope
.........................
I want to obtain this result in query(under the form of a list, dictionary, queryset, it doesn't matter which form):
concept_id definition prefLabel scope
1 blablabla prefferedLabel Scopeee
2 another definition another label another scope
How can I achieve this? Thanks
EDIT: I am using MySQL.
My ugly solution is this one
for concept_id in Concept.objects.all().values_list('id', flat=True):
Property.objects.filter(concept_id=concept_id, name__in=['prefLabel', 'scope', 'definition'])
.....
But is realy ugly, I want something different
THE SOLUTIONS OF pcoronel:
table = []
for concept in Concept.objects.all():
row = {'code': concept.id}
result=concept.property_set.filter(
name__in=['prefLabel', 'scope', 'definition'],
)
for r in result:
row.update({
r.name: r.value,
})
table.append(row)
Not sure if this is the best solution

Assuming your Property model has a field: models.ForeignKey('Concept', ...), you can simply follow that relationship backwards:
# iterate through Concepts and get desired related Properties using their name
for concept in Concept.objects.all():
concept.property_set.filter(name__in=['prefLabel', 'scope', 'definition'])

Related

Is there a way to create a unordered list with subitems from 1 content-type

I would like to create a organogram like:
https://codepen.io/bernardoantunes/pen/inrbh using 2sic Content.
I would like to create a content-type 'organogram' with the following fields:
Title as String
Parent as Entity (of type Organogram)
Description as String
Link as Hyperlink
Using this content-type i would add some elements where child elements could be created.
for example:
- Root
- Child 1 (Root is selected in the Parent field)
- Child 2 (Root is selected in the Parent field)
- Child 3 (Child 2 is selected in the Parent field)
Could this be done using 2sic content App?
I created the content-type and added some elements. Created a razor template and then it gives an error.
operator '==' can not be applied to operands of type System.Collections.Generic.List and ToSic.SexyContent.DynamicEntity
Razor template:
#using Connect.Koi;
#{
var first = AsDynamic(Data["Default"]).First();
var all = AsDynamic(Data["Default"]);
}
<div>#first.Title</div>
var children = all.Where(x => x.parent == first).ToList();
<div>#children.Count</div>
Basically the AsDynamic(...) creates wrapped entity-objects, whereas ...parent gives you a list of related items (because it could have more than 1 parent). If this is the code you want to use, I suggest 1 things.
On the .parent (which should probably be .Parent) use the [0] or .FirstOrDefault() so it's .Parent.FirstOrDefault() == first - remember to enable LINQ by #using System.Linq
Don't compare the AsDynamic objects, because they will be different objects. Better compare the id using .EntityId or something.
So you're resulting compare will probably be .Parent[0].EntityId == first.EntityId.
What I don't like about your solution is the idea, that the first item in the Default-list will somehow be the important one. This doesn't feel right, but I don't know your whole solution...

Get Taxonomy Term ID by Node in Drupal 8

I'm trying to get Taxonomy data by particular node.
How can I get Taxonomy Term Id by using Node object ?
Drupal ver. 8.3.6
You could do something like that:
$termId = $node->get('field_yourfield')->target_id;
Then you can load the term with
Term::load($termId);
Hope this helps.
If you want to get Taxonomy Term data you can use this code:
$node->get('field_yourfield')->referencedEntities();
Hope it will be useful for you.
PS: If you need just Term's id you can use this:
$node->get('field_yourfield')->getValue();
You will get something like this:
[0 => ['target_id' => 23], 1 => ['target_id'] => 25]
In example my field has 2 referenced taxonomy terms.
Thanks!
#Kevin Wenger's comment helped me. I'm totally basing this answer on his comment.
In your code, when you have access to a fully loaded \Drupal\node\Entity\Node you can access all the (deeply) nested properties.
In this example, I've got a node which has a taxonomy term field "field_site". The "field_site" term itself has a plain text field "field_site_url_base". In order to get the value of the "field_site_url_base", I can use the following:
$site_base_url = $node->get('field_site')->entity->field_site_url_base->value;
How to extract multiple term IDs easily if you know a little Laravel (specifically Collections):
Setup: composer require tightenco/collect to make Collections available in Drupal.
// see #Wau's answer for this first bit...
// remember: if you want the whole Term object, use ->referencedEntities()
$field_value = $node->get('field_yourfield')->getValue();
// then use collections to avoid loops etc.
$targets = collect($field_value)->pluck('target_id')->toArray();
// $targets = [1,2,3...]
or maybe you'd like the term IDs comma-separated? (I used this for programmatically passing contextual filter arguments to a view, which requires , (OR) or + (AND) to specify multiple values.)
$targets = collect($field_value)->implode('target_id', ',');
// $targets = "1,2,3"

Django 1.4 - query iteration using fields stored in a dictionary

I had a huge registration table with 112 fields. For a particular search I want to compare 17 fields & assign colors to variable say 'clrSelected'.
My code is :
reg = Regisration.objects.filter('some condition').order_by("name")
for r in reg:
if r.name=='abc': clrSelected='#fff'
if r.type=='1': clrSelected='#000'
if r.appl=='10': clrSelected='#c1ff51'
if r.code=='': clrSelected='#60c5f7'
if r.qlty=='first': clrSelected='#f99334'
...
...
there will be only one if condition, which need to be colored. Which means the field(from the dictionary) to be compared will change based on the user selection.
I want to access the field name from a dictionary like this
flds = {'1':'name', '2':'type', '3':'appl', '4':'code', '5':'qlty',...}
And use it something like this
if r.flds['1']=='abc': clrSelected='#fff'
How could i use the fields as above. I am using django 1.4 & python 2.7
Just to answer the question, you could use getattr:
if getattr(r, flds['1']) == 'abc': clrSelected = '#fff'
However, I am pretty sure that you could go with a different kind of implementation in this case which doesn't require using a dict like this.
I would suggest using a three tuple list: (fieldName, value, color)
some_list = [('name', 'abc', '#fff'), ('type', '1', '#000'), ...]
And, then use this list to determine the color:
for fieldName, value, color in some_list:
if getattr(r, fieldName) == value:
clrSelected = color
Looking at your implementation, it seems the color will be based on the last if condition which matches. If that is the case, you could create some_list in reverse order and break on the first matching condition.

dynamically placing a value in django query

I have following code:
hotels = models.Hotel.objects.filter(
wed=True,
county=hotel_main.county.id,
subscriptions__end_date__gte=datetime.date.today(),
subscriptions__enquiry_count__lte=F('subscriptions__tier__enquiry_limit'),
).filter(Q(x=TRUE|Q(y=True)).distinct()
And i have a list test = ['x','y','z','w']
The values of filter changes dynamically, so I use something like:
filter(Q(test[0]=TRUE|Q(test[3]=True))
which changes dynamically, but when I did that I got the following error:
Keyword can't be an expression
I know i can't use it there but let me know how to achieve this... Thank you!
Edit
I did as Chris suggested:
test[1] = {x: True}
and in my filter, I did as follows
filter(Q(test[1])).
it gave me below error:
need more than 1 value to unpack
Use a dictionary to set the keys and then expand it into kwargs with **, i.e.:
Q(**{test[0]: True})

ID/Key definitions in EMF (Meta) Models

I'm stuck with a very basic problem regarding EMF, here's what i've got.
EClass A:
aID : EInteger (Key: true)
EClass B:
bID : EInteger (Key: true)
EClass C:
Reference refA: to elements of A, containment: true, EKeys: aID, 0 .. n
Reference refB: to elements of B, containment: true, EKeys: bID, 0 .. n
Now here's the problem. In both my a and b list I'd like to have IDs from 0 to n. However, when I do this, I get the message:
The ID '1' of 'A' collides with that of 'B'
I hope my problem is described clearly. Does anyone know what I'm doing wrong? Thanks!
An EAttribute which is set as "ID" should be unique resource-wide. If you want to reference elements using a myReference[name="SomeName"] construction then you should use eKeys, then the eKeyed attribute should have a unique value within a reference.
I am under the impression you defined "aID" and "bID" as "ID's whereas that's not what you really want here.
That could be resolved using OO hierachy. You just need to extend A and B from a common Abstract class that contains the id attribute and it setted as ID in emf properties.
regards