bernardopires / django-tenant-schemas

Tenant support for Django using PostgreSQL schemas.
https://django-tenant-schemas.readthedocs.org/en/latest/
MIT License
1.46k stars 423 forks source link

Generate Queryset that spans all schemas #431

Closed garfonzo closed 7 years ago

garfonzo commented 7 years ago

I need a way to generate a queryset that spans across all schemas. For example:

class Ticket(models.Model):
    description = models.CharField()
    # ... more fields here

Then, a tenant that runs the following queryset: t = Ticket.objects.all() will only get their tickets.

However, I want a way to generate a queryset of tickets that is for all schemas. So, something along the lines of t_all_schemas = Ticket.objects.all() which returns all tickets across all schemas.

Is this possible? Can it be built?

garfonzo commented 7 years ago

To add a bit more clarity to my issue above, here's my scenario: I have a project that is for property maintenance companies. When there is some maintenance that needs done, they create a Ticket for that property. In the Ticket record, they assign a Vendor to the Ticket. Vendors are simply contact records that they have created.

However, I also have a "Vendor Portal" for vendors to log in and see which Tickets have been assigned to them (I'm using Django's Sites feature for the Vendor Portal). There's a high probability that multiple property maintenance companies using my SaaS will be using the same Vendor. So, I need the Vendor portal to be able to see Tickets created across multiple users -- ie: Tickets from across all schemas that have the Vendor set to them.

Hope that makes sense

alexandervaneck commented 7 years ago

Hi,

You could loop over every tenant that isn't a vendor and add the querysets together. This'll give you a list, but manipulating the tickets in the original database it came from is probably not going to work. Switching contexts between tenants can be hard.

from tenant_schemas.utils import tenant_context

all_tickets = Ticket.objects.none()
for tenant in TenantModel.objects.filter(is_vendor=False):
    all_tickets = all_tickets | Ticket.objects.filter(vendor=VENDOR)

return all_tickets

What about putting the tickets in the public schema? since this is a very special use case I think that would be a better solution.

bernardopires commented 7 years ago

You can do as suggested by @AlexvEck, however It really sounds like you're better off by having all tenants in the same schema for that use case. I think there is a django app that has that solution as well, but I don't recall the name right now.