1

I'm a little lost and don't know how to continue, after a lot of search I think that I'm not doing correctly it.

My problem is that I've got a offer class model like this one:

class Offer(models.Model):
    design_hours = models.IntegerField()
    design_price = models.DecimalField(max_digits=10, decimal_places=2)
    devel_hours = models.IntegerField()
    devel_price = models.DecimalField(max_digits=10, decimal_places=2)

    offer_price = models.DecimalField(max_digits=10, decimal_places=2)

Where offer_price is a calculated field (desig_hours * design_price + devel_hours * devel_price), I don't have problems overriding the save method.

class OfferAdmin(VersionAdmin):
    list_display = (
        'design_hours',
        'design_price',
        'devel_hours',
        'devel_price',
        'offer_price')

What I'd like to do is in the add/change form show a not editable field wich auto calculate when changing the design_hours or the design_prices form fields.

I supose that I have to override the change_form.html template but from here I don't know what to do :(

Thanks,

1 Answers1

0

Do you really need to save the offer_price in your database? It could always be recalculated from any model object, since all the required fields are there, and could be saved as a method for your object class.

If you decide that you do need to save this field in your database, then you'll need to add some sort of event logic in javascript to update the calculated value whenever your other inputs change.

You'll need to override your template as you thought. First, print everything out normally and then you can add a disabled tag to the offer_price input field (or better yet, create a new item that's not an input, such as a text field), then at the bottom add this script (assuming jQuery is imported in your template):

    // load jQuery
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script>
        // when any input in this form changes, call recalculate price
        $('#form_name input').on('change', reclaculate_price);

        var reclaculate_price = function(){
          // whatever your logic is for calculating the offer price
          var value = $('#design_hours').val() * $('#design_price').val();
          // Add some error checking here to ensure the price is valid
          // Set the value to you field
          $('#offer_price').val(value);
        }
    </script>

You'll need to change the id field names to whatever the appropriate fields are in your template.

Make sure the offer price saved in your database is calculated on the server-side because a malicious user could put whatever they wanted in the offer price field by flipping the disabled switch to enabled (see this post) It'd be best to override the ModelForm and exclude the offer_price field. Though hopefully you can trust the users in your admin, so this may not be required.

Community
  • 1
  • 1
shapiromatron
  • 569
  • 6
  • 11
  • Understand, thinking a little about storing the offer_price into the model maybe it is not needed. Solving the first question, I've got into the template the form line definition:
    and added at the botton of the template
    – antoniofcano May 01 '13 at 10:16