views:

211

answers:

1

Hi all,

I would like to know how you can change a model's field's parameters, not during model initialisation, but from a model admin. For instance, I would like to make either field "foo" or "bar" optional, according on a get parameter (wondering about the correct solution for the # PSEUDO CODE bit):

def add_view(self, request, form_url='', extra_context=None):
 if request.GET.get('object_type', 'foo') == 'foo':
  # PSEUDO CODE:
  model.fields.foo.blank = False
  model.fields.bar.blank = True
 else:
  # PSEUDO CODE:
  model.fields.foo.blank = True
  model.fields.bar.blank = False
 return super(FileNodeAdmin, self).add_view(request, form_url, extra_context)
+1  A: 

You will likely run into trouble since many of the fields' attributes are represented at the database level (i.e., if you do a manage.py syncdb with a field that has null=False, the DDL to create the database field will have NOT NULL). Dynamically changing the behavior of the database constraints is pretty close to impossible.

My prefered method of handling what you are describing would be at the form level and not at the model level. My models would be generic and allow all the allowable states (e.g. if in some cases a field can be null, but not other cases, just set null=True). I would then dynamically alter a django.form instance to change how it validates, or just do the validation manually in my view. You could even have to instances of a form, each with slightly different constraints and decide which one to use based upon your GET. In pseudo code:

def view(request):
    if request.GET.get('object_type', 'foo') == 'foo':
        f = FooForm(request) # FooForm let's bar be blank, while foo can not be blank
        if f.is_valid():
            a = f.cleaned_data['a']
            ...
    else:
        f = BarForm(request) # BarForm let's foo be blank, while bar can not be blank
        if f.is_valid():
            a = f.cleaned_data['a']
John Paulett