dbinetti
dbinetti

Reputation: 249

how to construct this Django ORM queryset query?

I'm trying to determine how to construct a query. I have two models from an external database that I"m trying to import into a different schema. The source data has three models:

class Group(model):
    ...
    name = models.CharField()

class Person(model):
    ...
    name = models.CharField()

class Membership(model):
    ...
    status = models.CharField()
    created_date = models.DateTimeField()
    modified_date = models.DateTimeField()
    person = models.ForeignKey(
        'Person',
        related_name='memberships',
    )
    group = models.ForeignKey(
        'Group',
        related_name='memberships',
    )

In the Memberships, I have fields representing the person and band, with create dates and update dates, as well as other relevant data.

Here's the problem: the Membership rows don't have any field that represents which is the canonical record, and they mix and match persons and dates and other data.

What I'm doing currently is taking all the Memberships for a given band, running distinct on them for the combination of band and person and using those results to query the Memberships again for the latest instance of each particular combination. While this works, as you might imagine is is unspeakably slow and I know there must be a better way.

So I'm looking for how to use some of the advanced django query expressions (Window? Over, F-expressions?) to get this done as much as possible on the database.

Here is the code that is getting me the records I want:

groups = (the groups I want)
for group in groups:
    unique_members = group.members.values(
        'person',
        'group',
    ).distinct()
    for member in members:
        current_member = group.members.filter(
            person__id=member['person'],
            group__id=member['structure'],
        ).lastest('created_date', 'modified_date')

With current_member being the most recent membership entry for that unique person/group combination.

So for a list of memberships like this:

Person           Group        Created     Status
John Lennon      Beatles      1960-01-01  Current
Paul McCartney   Beatles      1960-01-01  Current
Pete Best        Beatles      1960-01-01  Expired
George Harrison  Beatles      1960-01-01  Current
Ringo Starr      Beatles      1962-01-01  Expired
Pete Best        Beatles      1964-01-01  Expired
Ringo Starr      Beatles      1966-01-01  Current

I'd want the following list:

John Lennon      Beatles      1960-01-01  Current
Paul McCartney   Beatles      1960-01-01  Current
Pete Best        Beatles      1964-01-01  Expired
George Harrison  Beatles      1960-01-01  Current
Ringo Starr      Beatles      1966-01-01  Current

Generated from a single query.

Thanks!

Upvotes: 0

Views: 119

Answers (1)

Santiago M. Quintero
Santiago M. Quintero

Reputation: 1273

You can first order your members query by the desired entry then get the distict values. This question may help you:

Django query: get the last entries of all distinct values by list

Upvotes: 1

Related Questions