Populate Model from a Query with a One-to-Many Relationship - coldfusion

I have two tables:
surveyTemplateHeader
surveyTemplateQuestions
What I was looking to do was get the information from both tables:
var q = dao.getSurveyTemplateDetails( surveyTemplateID = ARGUMENTS.surveyTemplateID );
Then use Coldbox to populate my model, surveyTemplate, with the query data:
var surveyTemplateObj = populator.populateFromQuery( beanFactory.getInstance("surveyTemplate"), q );
This works, however, the model is only populated with one question. The surveyTemplate I am testing has three questions.
I have tried to set up a property name correctly in my model to use fieldtype="one-to-many" but that does not appear to have made a difference.
property name="surveyTemplateQuestionID" fieldtype="one-to-many";
While Coldbox's documentation for models overall is quite good, I am not able to find an answer for this, which probably means I am off track a good bit in my implementation of this.
Any insight would be appreciated.

So, what I did for this is I injected a surveyTemplateQuestions model into my surveyTemplate model:
property name="surveyTemplateQuestions" inject="surveyTemplateQuestions";
then I set the surveyTemplateQuestions property with the questions query:
surveyTemplateObj.setSurveyTemplateQuestions(qQuestions);
Not exactly what I was looking for but it works for now.

You can loop over query to build Arrays of objects. populateFromQuery method takes query row-number to get data from query.
var surveyTemplateObj = [];
for(var row in q){
ArrayAppend(surveyTemplateObj, populator.populateFromQuery( beanFactory.getInstance("surveyTemplate"), q , row.currentRow));
}
API Doc info
http://apidocs.ortussolutions.com/coldbox/4.3.0/coldbox/system/core/dynamic/BeanPopulator.html#populateFromQuery()

Related

How to populate table based on the condition of another table's column value in Django

I am kinda new in django and I am stuck.
I am building and app to store equipment registry. I have done a model for equipment list and i have a status values as "available", "booked", "maintenance"
I also have a model for all equipment that are not available. not in my html in the "not available registry" i want to show only details of equipment in the list that are marked as "booked" and "maintenance"
There are three ways of doing this.
To filter out objects of the model that are marked as "booked" or "maintenance" you can use complex lookups with Q objects. It allows you to filter objects with OR statement. Here you need to find objects that have status set to "booked" OR to "maintenance". The query should look like this:
from django.db.models import Q
Equipment.objects.filter(Q(status='booked') | Q(status='maintetnance'))
Second way of doing this is by using __in statement to filter objects that you need:
not_available_status = ['booked', 'maintenance']
Equipment.objects.filter(status__in=not_available_status)
And final way is to exclude objects that you don't need:
Equipment.objects.exclude(status='available')

How do you use SearchResult for join fields using Map/Reduce Script?

I'm starting to understand the Map/Reduce framework more and more for SuiteScript 2.0. However, all the help and SuiteAnswer articles show direct field relationships from the searchResult object.
How do you return a joined field as a Object Value during the map stage?
Example:
{"recordType":"manufacturingoperationtask","id":"1974","values":{"item.workOrder":{"value":"1517","text":"Agent Orange Pale Ale : AOP 1/2"},"enddate":"10/13/2017","formulanumeric":"65"}}
In this SearchResult object, I am trying to return the 1517 item internal id but haven't found a way to get it because the key is "item.workOrder".
I suppose if you just want to parse out the JSON string above, then it would be
var data = JSON.parse(result);
var workOrderId = data["item.workOrder"].value;
However, the typical way of accomplishing this through SuiteScript would be to use the Search Result Object's getValue method, along with its join option.
var workOrderId = result.getValue({
name: "workOrder",
join: "item"
});
FWIW I've written a whole series of example-driven cookbooks to help you master Searching in SuiteScript.

Django distinct foreign keys for use in another model

class Log:
project = ForeignKey(Project)
msg = CharField(...)
date = DateField(...)
I want to select the four most recent Log entries where each Log entry must have a unique project foreign key. I've tried the solutions on google search but none of them works and the django documentation isn't that very good for lookup..
I tried:
id_list = Log.objects.order_by('-date').values_list('project_id').distinct()[:4]
entries = Log.objects.filter(id__in=id_list)
id_list is empty unless I remove the order_by() but then it's not in the correct order.
entries = Log.objects.filter(id__in=id_list)
The objects in entries is not in the same order as in id_list because when you use Mysql function IN() it will not sort the result by the input order ... How to do it in django?
It looks like it is impossible to achieve what you want with django orm. Documentation states that is not possible to use order_by along with distinct.
However there might be another way to solve it. Maybe you could select Project objects, and annotate them with latest log entries.
Here's a single-query solution (but it will probably be too slow):
Log.objects.filter(project__log__date__gte=F('date')).annotate(c=Count('project__log')).filter(c__lte=4).order_by('project', 'c')
I think that Skirmantas is right and you have to do it in a more complex way:
from django.db.models import Max
projects = Project.objects.annotate(last_logged=Max('log__date')).order_by('-last_logged')[:4]
log_entries = [proj.log_set.order_by('-date')[0] for proj in projects]

django aggregate aggregated fields?

I have a model called Item, with m2m relation to User ("owner").
For each item, I need to count users who own it. That's easy enough with annotate()
But then I need to calculate ratio between owners of specific gender and total owner count for each item. For example if, 2 males own the item out of 5 users, the ratio is 0.4.
What's the best way to do that?
To do this with the ORM, you need conditional aggregates, which aren't supported in Django. http://www.voteruniverse.com/Members/jlantz/blog/conditional-aggregates-in-django proposes a hacky solution that might work.
If you don't need to sort by the ratio, then you can make two calls to annotate, and then compute the ratio in Python. Something like:
items = Item.objects.annotate(ucount=Count('users')).annotate(ccount=CountIf(<condition>))
for item in items:
item.ratio = item.ucount / item.ccount
If you don't want to do that, I'd recommend using the extra() method and some custom sql to get the extra info you want. Documentation for that method is on the Django Queryset API documentation page.
Just on top of my head, something like the following could work. Iterate on it to get your perfect solution if you wish:
items = Item.objects.annotate(Count('users'))
for item in items:
total = item.users__count
num_males = item.users.filter(gender='M').count()
num_females = item.users.filter(gender='F').count()

How do I get the related objects In an extra().values() call in Django?

Thank to this post I'm able to easily do count and group by queries in a Django view:
Django equivalent for count and group by
What I'm doing in my app is displaying a list of coin types and face values available in my database for a country, so coins from the UK might have a face value of "1 farthing" or "6 pence". The face_value is the 6, the currency_type is the "pence", stored in a related table.
I have the following code in my view that gets me 90% of the way there:
def coins_by_country(request, country_name):
country = Country.objects.get(name=country_name)
coin_values = Collectible.objects.filter(country=country.id, type=1).extra(select={'count': 'count(1)'},
order_by=['-count']).values('count', 'face_value', 'currency_type')
coin_values.query.group_by = ['currency_type_id', 'face_value']
return render_to_response('icollectit/coins_by_country.html', {'coin_values': coin_values, 'country': country } )
The currency_type_id comes across as the number stored in the foreign key field (i.e. 4). What I want to do is retrieve the actual object that it references as part of the query (the Currency model, so I can get the Currency.name field in my template).
What's the best way to do that?
You can't do it with values(). But there's no need to use that - you can just get the actual Collectible objects, and each one will have a currency_type attribute that will be the relevant linked object.
And as justinhamade suggests, using select_related() will help to cut down the number of database queries.
Putting it together, you get:
coin_values = Collectible.objects.filter(country=country.id,
type=1).extra(
select={'count': 'count(1)'},
order_by=['-count']
).select_related()
select_related() got me pretty close, but it wanted me to add every field that I've selected to the group_by clause.
So I tried appending values() after the select_related(). No go. Then I tried various permutations of each in different positions of the query. Close, but not quite.
I ended up "wimping out" and just using raw SQL, since I already knew how to write the SQL query.
def coins_by_country(request, country_name):
country = get_object_or_404(Country, name=country_name)
cursor = connection.cursor()
cursor.execute('SELECT count(*), face_value, collection_currency.name FROM collection_collectible, collection_currency WHERE collection_collectible.currency_type_id = collection_currency.id AND country_id=%s AND type=1 group by face_value, collection_currency.name', [country.id] )
coin_values = cursor.fetchall()
return render_to_response('icollectit/coins_by_country.html', {'coin_values': coin_values, 'country': country } )
If there's a way to phrase that exact query in the Django queryset language I'd be curious to know. I imagine that an SQL join with a count and grouping by two columns isn't super-rare, so I'd be surprised if there wasn't a clean way.
Have you tried select_related() http://docs.djangoproject.com/en/dev/ref/models/querysets/#id4
I use it a lot it seems to work well then you can go coin_values.currency.name.
Also I dont think you need to do country=country.id in your filter, just country=country but I am not sure what difference that makes other than less typing.