On May 18, 5:25 am, oneroler <samuel.ha...@gmail.com> wrote:
> Thanks Mike, that is what I was originally planning to do but realized
> there would be situations where that wouldn't do exactly what I wanted.
> For example, if there is a business that only has the strategy 'wholesale'
> assigned, using ForeignKey would still allow me to assign a different
> strategy to a division.  I was hoping to find a solution where the strategy
> for a division is constrained by the strategies assigned to its respective
> business.

Django doesn't make this particularly easy. You should create the
constraint in the database by using custom SQL, and then constraint
the assignable objects in Python in your view code. The Strategy and
Business models will create three tables into the database, one of the
tables is the many-to-many table. The m2m table's structure should be
something like this (check manage.py sqlall output):

create table business_strategy(
    id serial primary key,
    business_id integer references strategy(id),
    strategy id integer references business(id),
    unique (business_id, strategy_id)
)

Now, what you need to do is create a foreign key pointing to
business_id, strategy_id for your division table. The model should
look like this:

class Division(models.Model):
    business = models.ForeignKey(Business)
    name = models.CharField()
    strategy = models.ForeignKey(Strategy)

this creates a table (
     id serial primary key,
     business_id integer references business(id),
     name varchar(n),
     strategy_id integer references strategy(id),
)

You will need to drop the strategy_id -> strategy(id) foreign key by
hand and add a new one: business_id, strategy_id ->
business_strategy(business_id, strategy_id). Check your database
vendors docs for details how to do this. You will want this constraint
to be deferred if available on your DB.

So, now you should have correct constraint in the database. You will
still have some problems: changing division's business changes the set
of available strategies. On UI side you will probably need to create
an AJAX call on business changed to fetch the available strategies. In
forms code you will need to do something like this:

class DivisionForm(forms.ModelForm):
    class Meta:
          model = Division
    def __init__(self, **kwargs):
          # Note, intentionally restrict the forms usage to only
kwargs.
          super(DivisionForm, self).__init__(**kwargs)
          business_id = None
          if 'initial' in kwargs:
              business_id = kwargs['initial'].business_id
          if 'data' in kwargs and 'business_id' in kwargs['data']:
              business_id = kwargs['data']['business_id']
          self.fields['strategy'].queryset =
Strategy.objects.filter(business_set=business_id)

So, the restriction should be doable both in DB and Django, but isn't
trivial to do. The above is pseudo-code style, so the example code
will likely not work by copy-pasting...

 - Anssi

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to 
django-users+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-users?hl=en.

Reply via email to