I am not sure this is even possible without modifying the Admin interface.
I have a model called "Quote" that can contain multiple "Product" models. I connect the two using an intermediate model "Q开发者_如何学CuoteIncludes". Here are the three models as they currently stand:
class Product(models.Model):
name = models.CharField(max_length=100)
short_desc = models.CharField(max_length=200)
default_cost = models.DecimalField(max_digits=15, decimal_places=2)
default_price = models.DecimalField(max_digits=15, decimal_places=2)
shipping_per_unit = models.DecimalField(max_digits=9, decimal_places=2)
weight_in_lbs = models.DecimalField(max_digits=5, decimal_places=2)
def __unicode__(self):
return self.name
class Quote(models.Model):
## Human name for easy reference
name = models.CharField(max_length=100)
items = models.ManyToManyField(Product, through='QuoteIncludes')
def __unicode__(self):
return self.name
class QuoteIncludes(models.Model):
## Attach foreign keys between a Quote and Product
product = models.ForeignKey(Product)
quote = models.ForeignKey(Quote)
## Additional fields when adding product to a Quote
quantity = models.PositiveIntegerField()
per_unit_cost = models.DecimalField(max_digits=15, decimal_places=2)
per_unit_price = models.DecimalField(max_digits=15, decimal_places=2)
def _get_extended_price(self):
"""Gets extended price by multiplying quantity and unit price."""
if self.quantity and self.per_unit_price:
return self.quantity * self.per_unit_price
else:
return 0.00
extended_price = _get_extended_price
What I would like to be able to do is create a Quote in the Admin interface such that when I've filled in both the quantity and the per_unit_price of a line item, it fills in the "extended_price" as a product of the two when I tab over. I think it requires adding some AJAX in there.
Info on how to include js in your model admin: http://docs.djangoproject.com/en/dev/ref/contrib/admin/#modeladmin-media-definitions
For example:
class Media:
js = (
'http://ajax.googleapis.com/ajax/libs/jquery/1.4/jquery.min.js',
'/media/js/calculate.js',
)
And your script could look something like this:
function currencyFormat(nStr) {
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + '.' + '$2');
}
return x1 + x2;
}
jQuery(document).ready(function($){
$('input[id$=quantity], input[id$=per_unit_cost]').live('keyup', function() {
var $tr = $(this).parents('tr');
var quantity = parseInt($tr.find('input[id$=quantity]').val());
var count = parseInt($tr.find('input[id$=per_unit_cost]').val());
if(quantity && count) {
$tr.find('input[id$=per_unit_price]').html(currencyFormat(quantity * count));
}
});
});
Something like that.
Just added the currency format function in case you wanted to use it.
You won't easily get that field in to the change list there because it belongs to another model from the one being editied. You wil be able to include the through models as an inline below this model, though, and then you could simply write some JS that takes your two input fields and generates the output value you want and plonks it into the appropriate field on the through model that's included in the inline.
Or, write a custom view that doesn't lean on the admin ;o)
精彩评论