On Wed, Dec 10, 2008 at 7:58 PM, [email protected]
<[email protected]> wrote:
>
> One example is worth thousand explanations, so, let's say the
> situation is as follows:
>
> class example(models.Model):
> artist = models.CharField(max_length=765, blank=True)
> song_name = models.CharField(max_length=765, blank=True)
> id = models.IntegerField(primary_key=True)
>
> Three objects are created/save to a mysql db:
> 1 Django Reinhardt Liza
> 2 Django Reinhardt Minor Swing
> 3 Django Reinhardt Nuages
>
> example.objects.filter(artist="Django Reinhardt").distinct() returns
> all three objects, by making SQL query:
> SELECT DISTINCT `mainapp_example`.`artist`,
> `mainapp_example`.`song_name`, `mainapp_example`.`id` FROM
> `mainapp_example` WHERE `mainapp_example`.`artist` = Django
> Reinhardt .
>
> Lets say my goal is to get the list of (distinct) artists in a
> database, and it is reached by commiting query:
> SELECT DISTINCT `mainapp_example`.`artist` FROM `mainapp_example`
> WHERE `mainapp_example`.`artist` = Django Reinhardt .
> Only one row is returned - Django Reinhardt. Is it possible to get the
> same value using django-orm?
> That's probably how i was supposed to ask before.
Ok; now I understand the problem...
> Now i'm trying to get why this might be impossible - django queryset
> is probably supposed to (always) return objects, and in this case, its
> tuple ('Django Reinhardt',) or dictionary {'column': 'artist,
> 'row1':'Django Reinhardt'} i do expect to be returned. But please
> correct me if i'm wrong in past sentence, or anywhere in the post.
... and you've preempted my answer. What you're asking for can't be
retrieved with a simple query.
In order to get the distinct artist names, you need to restrict the
columns named in the select. You can do this with a values()
statement:
Song.objects.values('artist').distinct().
This will return a ValuesQuerySet, which acts much like a list of
dictionaries; each dictionary will have a single key-value pair. In
your example, the result would be something like:
[{'artist': 'Django Reinhardt'}]
If you're dealing with a single unique field (artist, in this case),
you can simplify the structure of the return value this by using a
call to values_list(), instead of values(). See the docs for more
details.
If all you want is the list of unique names, that's all you need to
so. However, in order to retrieve a QuerySet populated with full
Django objects, you need to put every column name in the SELECT. This
is done implicitly when you run Model.objects.all(), or any other
non-values() queryset.
This means that the requirements for the distinct call conflict with
the requirements for the object call. You can't make a simple 'SELECT
x FROM y WHERE z' where x satisfies both requirements.
However, you can do it by embedding one query in another - that is,
issue one query to get a list of unique names, then a second query to
retrieve a list of full objects that match those names. This can be
achieved in several ways, but something like the following should do
the trick:
Song.objects.filter(name__in=Song.objects.values_list('artist', flat=True))
Yours,
Russ Magee %-)
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Django users" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/django-users?hl=en
-~----------~----~----~----~------~----~------~--~---