Home > Software design >  How can I concatenate two different model query and order by a field that both models has
How can I concatenate two different model query and order by a field that both models has

Time:11-07

How can I concatenate two different model query and order by a field that both models has like progress fields.

For example

models.py

class Gig(models.Model):
    author= models.ForeignKey(User)
    title = models.CharFields()
    progress = models.IntegerField()

class Project(models.Model):

    author= models.ForeignKey(User)

    title = models.CharFields()

    progress = models.IntegerField()

Can I do my view.py like this, for me to achieve it?

İf No, How can I achieve it?

views.py

def fetch_all_item(request):
   gig = Gig.objects.filter(author_id = request.user.id)
   project = Project.objects.filter(author_id = request.user.id)
   total_item = (gig   project).order_by("progress")

   return render(request, "all_product.html", {"item": total_item})

I am trying to join two query set from Gig and Project models then send it to frontend in an ordering form by a field name called progress.

CodePudding user response:

You can let Python do the sorting for you, like:

from operator import attrgetter


def fetch_all_item(request):
    gig = Gig.objects.filter(author=request.user)
    project = Project.objects.filter(author=request.user)
    total_item = sorted([*gig, *project], attrgetter('progress'))
    return render(request, "all_product.html", {'item': total_item})

It might however be better to remodel this to a single model with a type field that disambiguates between a Gig and a Project.


Note: It is normally better to make use of the settings.AUTH_USER_MODEL [Django-doc] to refer to the user model, than to use the User model [Django-doc] directly. For more information you can see the referencing the User model section of the documentation.

CodePudding user response:

In general, such design when there are common fields is better accomplished by inheriting from some base class. E.g.:

class CommonActivity(models.Model):
    # common fields for Project/Gig
    author = models.ForeignKey(User)
    title = models.CharFields()
    progress = models.IntegerField()

class Gig(CommonActivity):
    pass   # or other fields related to Gig only

class Project(CommonActivity):
    pass

Then if you want to query both - you query CommonActivity.

If remodel not possible - then filter via Python as @WillemVanOnsem suggested.

However such filtering will be way less efficient

  • Related