citusdata / django-multitenant

Python/Django support for distributed multi-tenant databases like Postgres+Citus
MIT License
708 stars 116 forks source link

Adds many to many model tenant save #154

Closed gurkanindibay closed 1 year ago

gurkanindibay commented 1 year ago

In our project, we are trying to set tenant_id without user intervention. Our aim is making tenant set operation in one place and use that tenant everywhere in the application In issue #73, missing support of 'through model saves using ManyToMany relations' and in this PR I added this feature

codecov[bot] commented 1 year ago

Codecov Report

Merging #154 (a173977) into main (44db7b3) will increase coverage by 0.09%. The diff coverage is 100.00%.

@@            Coverage Diff             @@
##             main     #154      +/-   ##
==========================================
+ Coverage   98.01%   98.10%   +0.09%     
==========================================
  Files          32       34       +2     
  Lines        1006     1056      +50     
==========================================
+ Hits          986     1036      +50     
  Misses         20       20              
Impacted Files Coverage Δ
...roduct_purchase_store_alter_account_id_and_more.py 100.00% <100.00%> (ø)
...t/tests/migrations/0025_many_to_many_distribute.py 100.00% <100.00%> (ø)
django_multitenant/tests/models.py 100.00% <100.00%> (ø)
django_multitenant/tests/test_models.py 98.13% <100.00%> (+0.04%) :arrow_up:

:mega: We’re building smart automated test selection to slash your CI/CD build times. Learn more

rob101 commented 10 months ago

@gurkanindibay great solution. quick question; let's say you want to define the through model to add attributes to it. E.g., typically this would be as follows:

  class Store(TenantModel):
    tenant_id = 'id'
    name =  models.CharField(max_length=50)
    address = models.CharField(max_length=255)
    email = models.CharField(max_length=50)
    purchases = models.ManyToManyField(Product, through=Purchase)

  class Product(TenantModel):
    store = models.ForeignKey(Store)
    tenant_id='store_id'
    name = models.CharField(max_length=255)
    description = models.TextField()
    class Meta(object):
      unique_together = ["id", "store"]

  class Purchase(TenantModel):
    store = models.ForeignKey(Store)
    tenant_id='store_id'
    product = TenantForeignKey(Product)
    date = models.DateField()

This means when you call store.purchases.add(Purchase()), you will get TypeError: Purchase() got multiple values for keyword argument 'issuer_id'.

How would you handle this? Remove the TenantModel mixin from Purchase?