I am working on top of an existing project, I am not allowed to make migrations to the current model. Suppose I have a model like this:
class Things(models.Model):
name = models.CharField(max_length=255)
objs = Things.objects.values('name')
will give me the following result
|objs|
|----|
|apple|
|orange|
|banana|
|fruits|
|car|
|bus|
|motorcycle|
|autombiles|
so if i do : somequery = objs.some_function(), how do i get the following result, assuming its possible.
|cats | objs |
|------------------ |
|automobiles|car |
|automobiles|bus |
|automobiles|motorcycle|
|fruits |apple |
|fruits |orange |
|fruits |banana |
-------------------------
from what I read about this so far, there isn't a straightforward way of solving this without altering the models.py. Any help/suggestion will help me tremendously.
Related
I have a group of people who started receiving a specific type of social benefit called benefitA, I am interested in knowing what(if any) social benefits the people in the group might have received immediately before they started receiving BenefitA.
My optimal result would be a table with the number people who was receiving respectively BenefitB, BenefitC and not receiving any benefit “BenefitNon” immediately before they started receiving BenefitA.
My data is organized as a relation database with a Facttabel containing an ID for each person in my data and several dimension tables connected to the facttabel. The important ones here at DimDreamYdelse(showing type of benefit received), DimDreamTid(showing week and year). Here is an example of the raw data.
Data Example
I'm not sure how to approach this in PowerBi as I am fairly new to this program. Any advice is most welcome.
I have tried to solve the problem in SQL but as I need this as part of a running report i need to do it in PowerBi. This bit of code might however give some context to what I want to do.
USE FLISDATA_Beskaeftigelse;
SELECT dbo.FactDream.DimDreamTid , dbo.FactDream.DimDreamBenefit , dbo.DimDreamTid.Aar, dbo.DimDreamTid.UgeIAar, dbo.DimDreamBenefit.Benefit,
FROM dbo.FactDream INNER JOIN
dbo.DimDreamTid ON dbo.FactDream.DimDreamTid = dbo.DimDreamTid.DimDreamTidID INNER JOIN
dbo.DimDreamYdelse ON dbo.FactDream.DimDreamBenefit = dbo.DimDreamYdelse.DimDreamBenefitID
WHERE (dbo.DimDreamYdelse.Ydelse LIKE 'Benefit%') AND (dbo.DimDreamTid.Aar = '2019')
ORDER BY dbo.DimDreamTid.Aar, dbo.DimDreamTid.UgeIAar
I suggest to use PowerQuery to transform your table into more suitable form for your analysis. Things would be much easier if each row of the table represents the "change" of benefit plan like this.
| Person ID | Benefit From | Benefit To | Date |
|-----------|--------------|------------|------------|
| 15 | BenefitNon | BenefitA | 2019-07-01 |
| 15 | BenefitA | BenefitNon | 2019-12-01 |
| 17 | BenefitC | BenefitA | 2019-06-01 |
| 17 | BenefitA | BenefitB | 2019-08-01 |
| 17 | BenefitB | BenefitA | 2019-09-01 |
| ...
Then you can simply count the numbers by COUNTROWS(BenefitChanges) filtering/slicing with both Benefit From and Benefit To.
I have two models, route and stop.
A route can have several stop, each stop have a name and a number. On same route, stop.number are unique.
The problem:
I need to search which route has two different stops and one stop.number is less than the other stop.number
Consider the following models:
class Route(models.Model):
name = models.CharField(max_length=20)
class Stop(models.Model):
route = models.ForeignKey(Route)
number = models.PositiveSmallIntegerField()
location = models.CharField(max_length=45)
And the following data:
Stop table
| id | route_id | number | location |
|----|----------|--------|----------|
| 1 | 1 | 1 | 'A' |
| 2 | 1 | 2 | 'B' |
| 3 | 1 | 3 | 'C' |
| 4 | 2 | 1 | 'C' |
| 5 | 2 | 2 | 'B' |
| 6 | 2 | 3 | 'A' |
In example:
Given two locations 'A' and 'B', search which routes have both location and A.number is less than B.number
With the previous data, it should match route id 1 and not route id 2
On raw SQL, this works with a single query:
SELECT
`route`.id
FROM
`route`
LEFT JOIN `stop` stop_from ON stop_from.`route_id` = `route`.`id`
LEFT JOIN `stop` stop_to ON stop_to.`route_id` = `route`.`id`
WHERE
stop_from.`stop_location_id` = 'A'
AND stop_to.`stop_location_id` = 'B'
AND stop_from.stop_number < stop_to.stop_number
Is this possible to do with one single query on Django ORM as well?
Generally ORM frameworks like Django ORM, SQLAlchemy and even Hibernate is not design to autogenerate most efficient query. There is a way to write this query only using Model objects, however, since I had similar issue, I would suggest to use raw query for more complex queries. Following is link for Django raw query:
[https://docs.djangoproject.com/en/1.11/topics/db/sql/]
Although, you can write your query in many ways but something like following could help.
from django.db import connection
def my_custom_sql(self):
with connection.cursor() as cursor:
cursor.execute("SELECT
`route`.id
FROM
`route`
LEFT JOIN `stop` stop_from ON stop_from.`route_id` = `route`.`id`
LEFT JOIN `stop` stop_to ON stop_to.`route_id` = `route`.`id`
WHERE
stop_from.`stop_location_id` = %s
AND stop_to.`stop_location_id` = %s
AND stop_from.stop_number < stop_to.stop_number", ['A', 'B'])
row = cursor.fetchone()
return row
hope this helps.
I'm trying to order my concerts by the number of reviews each has. Concert has_many reviews. Tried doing this
<% #concerts = Concert.all %>
<% #concerts.order(reviews.size).each do |concert| %>
-
-
-
<% end %>
but I get this error
undefined method `review' for
ActiveRecord::Relation::ActiveRecord_Relation_Concert:0xb5540398>
Any suggestions how I would reference the number of reviews each has to order the concerts?
Not the best, but the simplest solution is
#concerts = Concert.all.includes(:reviews).sort_by{|concert| concert.reviews.size}.reverse
An alternative to the other answer which will ultimately give you the same result set, but will have slightly different side effects:
Concert.select("concerts.*, count(reviews.id) review_count")
.joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id")
.group("concerts.id")
.order("review_count")
The main difference is that this query will not immediately execute until it is used; you'll receive an active record relation, just as you normally would when using any of the active record query methods, which means you can further refine or add to the query (hypothetically speaking).
Another difference is that this query does not require eager loading of reviews. Depending on your needs, if you don't require any information from the related reviews, this query will run considerably faster.
As far as timing / performance goes, using a database of 50 concerts and 43867 reviews (index exists on FK), both versions seem to execute in approximately the same time (with eager loading). Here's a table of my benchmarking results (all results are in seconds):
| # | Sory_by Query | Pure AR Query | No eager loading |
--------------------------------------------------------
| 1 | 2.899806 | 2.840702 | 0.02164 |
| 2 | 3.150556 | 2.818374 | 0.21612 |
| 3 | 2.812867 | 3.025921 | 0.016368 |
| 4 | 3.069562 | 3.055307 | 0.016884 |
| 5 | 2.862722 | 2.680357 | 0.021316 |
|---|---------------|---------------|------------------|
AVG: 2.9591026 | 2.8841322 | 0.0584836 |
As you can see, there's no significant difference between the two queries using eager loading, and a major difference using my query above without eager loading. Obviously, the exact results will be different for you, but this should give you an idea of the relative differences.
Side note:
From what you posted in the question, it seems you are/were wanting to write this query in the ERB view. I would strongly advice moving this query to a method in the Concert model, and creating an instance variable from the return of that method in the controller which the view can then use. That way you keep everything nice and separated.
Edit
To illustrate my recommendation, I would place the query in a class method of the Concert model, like so:
def self.ordered_by_reviews
return select("concerts.*, count(reviews.id) review_count")
.joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id")
.group("concerts.id")
.order("review_count")
end
Which you can call from your controller (doesn't matter which controller):
... other controller code:
#concerts = Concert.ordered_by_reviews
... and so on
You can then use #concerts as you need and can remove any stuff like #concerts = Concert.all and such.
Alternatively, you can also use scopes to do the same thing (which I believe would be considered more Rails-y anyways):
class Concert < ActiveRecord::Base
scope :ordered_by_review, -> { select("concerts.*, count(reviews.id) review_count").joins("LEFT JOIN reviews ON concerts.id = reviews.concert_id").group("concerts.id").order("review_count") }
... rest of class
I have a set of django models that are set out as follows:
class Foo(models.Model):
...
class FooVersion(models.Model):
name = models.CharField(max_length=100)
parent = models.ForeignKey(Foo)
version = models.FloatField()
...
I'm trying to create a Django ListView that displays all Foos, in alphabetical order by the name of their highest version. For example, if I have a data set that looks like:
version_id | id | version_name | version
-----------+----+-----------------------------------+---------
1 | 1 | Test 1 | 1.0
2 | 1 | Test 2 | 2.0
3 | 1 | Test 2 | 3.0
4 | 2 | Test 1 | 1.0
5 | 1 | Test 3 | 2.5
6 | 3 | Test 3 | 1.0
I want the query to return:
version_id | id | version_name | version
-----------+----+-----------------------------------+---------
4 | 2 | Test 1 | 1.0
3 | 1 | Test 2 | 3.0
6 | 3 | Test 3 | 1.0
The raw sql I would use to generate this is:
SELECT version_class.id as version_id, someapp_foo.id, version_class.name as version_name, version_class.version
FROM someapp_foo
INNER JOIN(
SELECT someapp_fooversion.name, someapp_fooversion.version, someapp_fooversion.parent_id, someapp_fooversion.id
FROM someapp_fooversion
INNER JOIN(
SELECT parent_id, max(version) AS version
FROM courses_courseversion GROUP BY parent_id)
AS current_version ON current_version.parent_id = someapp_fooversion.parent_id
AND current_version.version = someapp_fooversion.version)
AS version_class ON version_class.parent_id = someapp_foo.id
ORDER BY version_name;
But I'm having trouble using a raw query because the RawQuerySet object doesn't have a 'count' method, which is called by ListView for pagination. I've looked into the 'extra' feature of Django querysets, but I'm having trouble formulating a query that will work with that.
How would I formulate a query for 'extra' that would get me what I'm looking for? Or is there a way to convert a RawQuerySet into a regular QuerySet? Any other possible solutions to get the results I'm looking for?
There may be a better way to do this, but for now I'm trying a custom solution that seems to work:
from django.db import models
from django.db.models.query import RawQuerySet
class CountableRawQuerySet(RawQuerySet):
def count(self):
return sum([1 for obj in self])
class FooManager(models.Manager):
def raw(self, raw_query, params=None, *args, **kwargs):
return CountableRawQuerySet(raw_query=raw_query, model=self.model, params=params, using=self._db, *args, **kwargs)
class Foo(models.Model):
objects = FooManager()
Then my queryset is:
Foo.objects.raw(sql)
Suggestions on how to improve this?
First of all - your solution is wrong and very uneffective with a big amount of data.
I believe you just need something like:
from django.db.models import Max
Foo.objects.annotate(max_version=Max(fooversion__version))
You can now reffer to max_version attribute in each result as to normal attribute.
Please see https://docs.djangoproject.com/en/dev/topics/db/aggregation/ for details.
One other point to add is that RawQuerySet works fine with a ListView as long as you don't use pagination, i.e. you can just leave out the paginate_by = NN attribute from your ListView subclass.
I want to make an form for purchasing tickets. The problem is that for every event there can be diferent types of ticket with diferent price.
For every kind of ticket I will have to create an edit box where user can select how much tickets he wants.
Then in view class I will just display the dynamicly created form ... the only problem that I see now is that I don't know where to save an information for each ticket price so I can easy display it in the the same row where the edit box is?
P.S. I'm also not sure how can I dynamicly create a form using Django ... but this have to be easy ;)
P.S. Form have to be something like this:
--------------------------------------------------------
| Tiket Type | Price | How much? | Price |
--------------------------------------------------------
| Tiket Type Name | Price $1.00 | [ ] | Price... | [tiketkind.id = 1]
| Tiket Type Name | Price $2.00 | [ ] | Price... | [tiketkind.id = 12]
| Tiket Type Name | Price $3.00 | [ ] | Price... | [tiketkind.id = 18]
| Tiket Type Name | Price $4.00 | [ ] | Price... | [tiketkind.id = 21]
--------------------------------------------------------
| TOTAL PRICE: | ... |
--------------------------------------------------------
| Email: [ ] |
--------------------------------------------------------
This is pretty easy. Instead of thinking about making dynamic forms, think about making dynamic fields.
You'll have one form. When you initialize it, you'll pass it information about the tickets available. In the init of your form you will dynamically add field objects to the form by appending to self.fields.
Example:
self.fields['this_field_I_just_made_up'] = forms.CharField()
Notes:
The first thing you'll need to do in your init is to pop off your custom values.
The second thing you'll need to do in your init is to call the init of the superclass with *args and **kwargs.
If you don't do those two things, in that order, you will get errors.
Shawn
Source: http://groups.google.com/group/django-users/browse_thread/thread/3629184ceb11aeef
First of all, you're thinking in PHP. Don't do that. There's no need for array-like HTML element names.
I'm not entirely sure I understand your requirements, but it sounds like a formset will do what you want.