Django and computed fields in a legacy database
I am gradually replacing a legacy database front end with a django based system. All models are Managed = F开发者_StackOverflowalse, to preserve the original db structure.
However I have struck a problem where a field in a table is computed. The field is defined in (pseudo) sql as full_name = fname|| ||lname.
I can define the full_name field as a charfield; and I can read it no problems, however any attempt to update the record results in an update error on that field.
I can use a @property; but that replicates the functionality in django, rather than displaying the results from the db itself. Using this approach will cause problems with more complex fields (in tables I am yet to get to) that are defined with UDFs.
What is really needed is a 'read_only' or 'computed' attribute on the model itself; what is the best way to achieve this?
Do you just want to define a method in your class? Something like:
def Person(models.Model):
fname=models.CharField(...)
lname=models.CharField(...)
def fullname(self):
return self.fname+" "+self.lname
(not exactly sure what Managed=False means...)
if you are trying to make calculation on a database models and pass the value of a model field to another model field of the same class model, using a defined function then this solution might help you. for example lets assume you have an investment company and you give 20% per month for the capital each user invested, you would want want to pass value from capital model to a function that calculates the percentage interest, and then you will pass that function into another field monthly_payment and get saved in the database.
1) pip install django-computed-property
2) add 'computed_property' to your installed apps in project settings.
3) in your models.py, import computed_property then
class Investment(models.Model):
name = models.CharField(max_length=200)
capital = models.FloatField(null=False)
percentage = models.CharField(max_length=5)
duration = models.CharField(max_length=10, default="1 months")
monthly_payment = computed_property.ComputedFloatField( compute_from='monthly_percentage', null=False, blank=False)
then your function to perform the calculation will go thus
@property
def monthly_percentage(self):
return (20 / 100) * self.capital
Note: what i discovered was if you use the inbuilt django fields be it FloatFiled or IntegerField, this function won't read the amount you are passing in to get your 20% calculations.i hope this works for you as i stated all as they worked for me,cheers.
精彩评论