0

I've got a set of key, value pairs dictionary in my Django application. The value in the dictionary is a string type.

{u'question': u'forms.CharField(max_length=512)'}

I need to convert this "value" string to an actual object, and get something like this.

properties = {
    'question' : forms.CharField(max_lenth=512)
    }

Notice that values in the second dictionary are actual Django form fields and NOT strings. I need to do this manipulation to create dynamic forms. The second dictionary is to be passed to "type" built-in function. Sample code can be found on this page. http://dougalmatthews.com/articles/2009/dec/16/nicer-dynamic-forms-django/ .

4
  • 2
    Oh urgh. I can suggest a nicer representation if you like. Commented Mar 14, 2011 at 8:51
  • @ignacio : Sure. I'm just learning stuff here. The only constraint is that I need to create forms on the fly/dynamically. Commented Mar 14, 2011 at 8:53
  • What Python version are you using Neo? Commented Mar 14, 2011 at 8:59
  • @mahmoud - standard 2.6. Commented Mar 14, 2011 at 9:00

3 Answers 3

3

If you modify your representation a bit:

fields = {u'question': u'{"field": "django.forms.CharField", "params": {"max_length": 512}}'}

then you can use the following:

from django.utils import importlib, simplejson

def get_field(fname):
  module, name = fname.rsplit('.', 1)
  return getattr(importlib.import_module(module), name)

print dict((k.encode('ascii', 'ignore'), get_field(v['field'])(**v['params']))
  for k, v in ((k, simplejson.loads(v)) for k, v in fields.iteritems()))
Sign up to request clarification or add additional context in comments.

Comments

1

Following your code, I suggest to separate field name from field attrs:

my_fields = {u'question': {'name': 'CharField', 'attrs': {'max_length': 512} }} 

and then something like:

properties = {}
for field_name, field_def in my_fields.items():
    properties[field_name] = getattr(forms, field_def['name'])(**field_def['attrs'])

Comments

0

EDIT: Based on clarifying comments by the OP, this isn't an appropriate solution.


I don't know the constraints you are under, but perhaps the following representation will work better:

{u'question': lambda: forms.CharField(max_length=512)}

You can then "realise" the fields thus:

dict((k, v()) for (k, v) in props.iteritems())

5 Comments

That's not really a representation though.
@Ignacio: "Representation" is an extremely broad term that covers statements like, "A lambda function is a representation of a computation". Perhaps you had a more narrowly-defined meaning in mind.
The question I've posted is a sort of simplification. Actually, I have a database model, that stores Field and corresponding django form field. Ex "Char" -> "form.Charfield(max_lenght=512)" etc. So depending on user input, I retrieve a corresponding string for each field type. Should I store something other than string my model database?
@Neo: In that case, what you are doing is probably the simplest solution. You can convert any string representing a Python value back to that value using Python's eval function.
Using eval gives me the following error 'module' object has no attribute 'CharField'. Maybe I should statically declare the objects types in the file as a dictionary, rather than the database.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.