First, I am stuck using django 0.91 because I make extensive use of model inheritance and how it works in 0.91.
I am wondering how to do something with AddManipulators vs ChangeManipulators. The basic issue is that I have a bunch of models that have some fields only settable on create vs settable at anytime. The reason for this is that I am representing objects from another service using the django framework to provide a better experience when manipulating that other (non-web based) service. Some fields on the object, such as its 'name' are only settable on create. Fine, so in my models I define those fields as 'editable = False' (they should not be editable on a page that displays a form generated from that object's ChangeManipulator.) Now, in my "create_object" view I thought I was clever by augmenting the AddManipulator I get back from the module to add in the form fields that should only be present on 'create' of this object: -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ ############################################################################ # @login_required def client_create(request, eng_id): """The view that is used to create a client object. It is pretty simple. The biggest trick is that we add to the django provided AddManipulator the fields on the client object that are only settable on create. We also properly flag the fields that are required on create. """ engine = engineinstances.get_object(pk = eng_id) manipulator = clients.AddManipulator() # We need to add the fields to the manipulator that are only valid when # creating a new client object. (ie: settable on create), and we must # the ones that are required as required (ie: required on create) # manipulator.fields.extend([ formfields.TextField(field_name="name", is_required = True, length=30, maxlength = 1024), formfields.TextField(field_name="dhcp_client_identifier",length=30, maxlength = 1024), formfields.TextField(field_name="hardware_address",length=30, maxlength = 1024), ]) if request.POST: # If data was POSTed, we're trying to create a new Client. new_data = request.POST.copy() new_data['gecko_engine_instance'] = engine.id new_data['gecko_locally_modified'] = 'c' # If dhcp_client_identifier is not set but hardware address is then # derive the dhcp_client_identifier from the hardware address # if new_data['dhcp_client_identifier'] == "": dhcid = mac_to_dhcid(new_data['hardware_address']) new_data['dhcp_client_identifier'] = dhcid print "Post is: %s\nNew data is: %s" % (str(request.POST), str(new_data)) errors = manipulator.get_validation_errors(new_data) if not errors: # No errors. This means we can save the data! manipulator.do_html2python(new_data) new_obj = manipulator.save(new_data) # Redirect to the object's "edit" page. Always use a redirect # after POST data, so that reloads don't accidently create # duplicate entries, and so users don't see the confusing # "Repost POST data?" alert box in their browsers. return HttpResponseRedirect(new_obj.get_absolute_url()) else: print "client create had errors: %s" % errors else: # No POST, so we want a brand new form without any data or errors. errors = {} new_data = {} # Create the FormWrapper, template, context, response. form = formfields.FormWrapper(manipulator, new_data, errors) t = template_loader.get_template('dcs/client_create') c = Context(request, { 'engine' : engine, 'form' : form, 'obj_type' : Client.__name__, }) return HttpResponse(t.render(c)) -+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ The bits where I do: new_data['gecko_engine_instance'] = engine.id new_data['gecko_locally_modified'] = 'c' is because I am creating a new object, and setting one field (that is a ForeignKey) to the object it points to. The other field is also set to indicate that I hae 'created' this object locally. These two fields are marked 'editable = True' because that was the only way to get them INTO the new object. This is rather hackish though. The issue is that this does not work. Since the 'name', 'dhcp_client_identifier', and 'hardware_address' fields are not marked as "editable" in the object model, they are NOT copied from the data in the HTML form. It was annoying to find out that 'editable' had this somewhat obscure meaning. Now, I could mark them 'editable' and then things would work here. However, in the "change" form where you can modify an object I would need to add lines like new_data['name'] = orig_obj.name where "orig_obj" is the original object retrieved from the ChangeManipulator. If I had to do that then I would have to write every change view such that it knew which fields were only settable on create. I could do this. All this information is actually derived programmatically from a series of XML schemas describing the object data formats. However that is a bit annoying. I am wondering if there is a simple, safe, way to add code to the view that uses the AddManipulator so that these fields I have added to the form get copied over to the new object being created. I guess the gist is I can think of some ways to do this. Some seem more hackish then others. Having stuff that derives data from a programmatically generated dictionary that tells me which feels to add to the django created AddManipulator seems a lot simpler then adding code that knows how to fill these fields in after the form is posted in the ChangeManipulator. Another option is to perhaps sub-class and replace somehow the django generated AddManipulator to use some other source for which fields should be copied over from the form to the object _before_ the object is saved to the db. Oh, one thing I forgot to mention - the problem happens in the AddManipulator's "obj.save()" that is called early on, because the "name" field is defined as needing to be not-null. This is because strictly speaking in terms of the data I am representing it should never be null. THe reason it is null at the tim eof the "obj.save()" call is because the data is not copied over the data in the form those fields not marked editable, yada yada. I could make the field allowed to be null, but the data purist in my is not happy with that solution because that field should never be null, even if it is for a short while, and for a number of good reasons I do not want to weaken this aspect of the data model. If there is a fantastic way to do this in the magic-removal mainline I would probably figure out how to jury-rig my models so that I could deal with the current lack of sub-classing support. I am looking for some insight in to how this sort of thing should be resolved. Multiple suggestions are appreciate. --Scanner --~--~---------~--~----~------------~-------~--~----~ 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 [EMAIL PROTECTED] For more options, visit this group at http://groups.google.com/group/django-users -~----------~----~----~----~------~----~------~--~---