Computed fields Odoo9 - python-2.7

I'm creating a module for student management in "Odoo9", in a part of that module I want to compute the average mark that a student get in a subject like "maths".I'm tryingto achieve that using this code, but I have a problem computing the "Avg-Maths" immediately after filling "Maths-1" and "Maths-2", it can only be computed after saving the student profile.Can someone help me please realizing the issue here? and how can I fix this?
#student class
class student_student(models.Model):
'
'
'
result_ids = fields.One2many("schoolresults.detail", "student_id", "School Results")
'
'
'
class schoolresults_detail(models.Model):
_name = "schoolresults.detail"
_description = "Student's results."
student_id = fields.Many2one("student.student", "Student", ondelete="cascade")
subject_id = fields.Many2one("schoolresults.subject", "Subject")
result_manual = fields.Float("Result")
result = fields.Float(compute='_compute_value',store=True)
manual = fields.Boolean(compute='_is_manual', default=False)
#api.one
#api.depends('manual')
def _is_manual(self):
self.manual = self.subject_id.my_id
#api.one
#api.depends('result_manual','subject_id','subject_id.my_id')
def _compute_value(self):
self.ensure_one()
results = self.env['schoolresults.detail'].search([])
total = 0
for data in results:
total += data.result_manual
for data in results:
#if the subject is the average of others
if data.subject_id.my_id:
data.result = total
class schoolresults_subject(models.Model):
_name = "schoolresults.subject"
_description = "Student's subjects."
my_id = fields.Integer(default=0)
name = fields.Char("Subject")

Add student_id.result_ids.result_manual to your depends list on _compute_value. That should trigger a recomputation.

i think after calculating the value you should assign it to your result field
#api.one
def _compute_method(self):
# compute average for this record
self.result = calclated_value
but i don't see that you assign the value to the result field ?!! sot try to assign it that should do it

Related

Django validation of number from query string

Im having this code to create and add students to database.
I need to make validation of count which must be integer, only positive, equal or less 100.
Please help.
def generate_students(request):
count = request.GET.get('count')
studentslist = []
for student in range(0, int(count)):
student = Student.objects.create(first_name = fake.first_name(), last_name = fake.last_name(), age = random.randint(18,100))
studentslist.append(student)
output = ', '.join(
[f"id = {student.id} {student.first_name} {student.last_name}, age = {student.age};" for student in studentslist]
)
return HttpResponse(str(output))
The best way is likely to work with a form, since a form has a lot of validation inplace, can clean the object, and print sensical errors.
We thus can work with a simple form:
from django import forms
class CountForm(forms.Form):
count = forms.IntegerField(min_value=1, max_value=100)
then we can validate the input with:
def generate_students(request):
form = CountForm(request.GET)
if form.is_valid():
count = form.cleaned_data['count']
studentslist = [
Student.objects.create(first_name = fake.first_name(), last_name = fake.last_name(), age = random.randint(18,100))
for _ in range(count)
]
output = ', '.join(
[f'id = {student.id} {student.first_name} {student.last_name}, age = {student.age};'
for student in studentslist]
)
else:
return HttpResponse(str(form.errors))
return HttpResponse(str(output))
Note: Section 9 of the HTTP protocol
specifies that requests like GET and HEAD should not have side-effects, so you
should not change entities with such requests. Normally POST, PUT, PATCH, and
DELETE requests are used for this. In that case you make a small <form> that
will trigger a POST request, or you use some AJAX calls.

Name error when trying to print an object of a class

I'm new to python and need some help. My code is below. I'm trying to get the formatted table from a list of user details inputted but keep getting error stating 'NameError: name 'games' is not defined' Not sure what I am doing wrong to get it to print, please help.
class game():
def _init_(self,name,platform,genre,no_of_players,online_functionality):
self.name = name
self.platform = platform
self.genre = genre
self.no_of_players = no_of_players
self.online_functionality = online_functionality
def __repr__(self):
print()
print("%-15s%-15s%-15s%-15s%-15s" % ("name" , "platform" ," genre" ,"no_of_players","online_functionality"))
print("---------------------------------------------------------------------------------")
print("%-10s%-10s%-10s%-10s%-10s%" %(games.name,games.platform,games.genre,games.no_of_players,games.online_functionality))
print()
def __str__(self):
print()
print("%-15s%-15s%-15s%-15s%-15s" % ("name" , "platform" ," genre" ,"no_of_players","online_functionality"))
print("------------------------------------------------------------------------")
print("%-10s%-10s%-10s%-10s%-10s%" %(games.name,games.platform,games.genre,games.no_of_players,games.online_functionality))#formats and aligns columns
print()
def get_game_from_user():
gameList =[]
games = game()
games.name= input("Enter name of game: ")
games.platform= input("Enter Platform (e.g. XBox, PlayStation, PC etc: ")
games.genre = input("Genre (e.g. Sport, Shooter, Simulation etc.): ")
games.no_of_players= int(input("Enter number of players: "))
games.online_functionality= input("Enter if it has online functionality or not : ")
gameList.append(games)
print(gameList)
First Problem:
Use self inside your class to access to your object not games. change these:
games.name, games.platform , games.genre, ...
and other stuffs like them to these:
self.name, self.platform , self.genre, ...
Second problem:
in your code is that you must return what you want inside the __str__ and __repr__ not print them:
def __repr__(self):
result = ""
result += "%-15s%-15s%-15s%-15s%-15s" % ("name" , "platform" ," genre" ,"no_of_players","online_functionality\n")
result += "---------------------------------------------------------------------------------\n"
result += "%-10s%-10s%-10s%-10s%-10s" %(self.name,self.platform,self.genre,self.no_of_players,self.online_functionality)
result += "\n"
return result
source: python data model

How to store/create data with multiple dates for the same timetable

I have a model of a timetable as below:-
class time_table(models.Model):
username = models.ForeignKey(User,db_column="username", on_delete=models.CASCADE,)
sem_section = models.ForeignKey(sem_sections, db_column = "sem_section",on_delete=models.CASCADE,)
subject_id = models.ForeignKey(subjects,db_column="subject_id", on_delete=models.CASCADE,)
day_name = models.ForeignKey(days_ref, db_column = "days_ref",on_delete=models.CASCADE,)
hour_no = models.ForeignKey(hours, db_column = "hour_no",on_delete=models.CASCADE,)
def __str__(self):
ret = str(self.username) +' takes ' + str(self.sem_section) + " class " + str(self.subject_id) + " on " + str(self.hour_no) + " on " + str(self.day_name);
return ret
class Meta:
constraints = [
models.UniqueConstraint(fields=['sem_section', 'day_name', 'hour_no'], name='Allotment_check')
]
I have to create multiple records that repeat for each tuple that is inserted like if i insert a slot for monday 4th hour having some subject it must be created for multiple recurring dates of the whole year or semester.
Any sugestions on how to tweak the code or any extra code to add to achieve this goal.
I am using Postgres for database.
You can use Django's bulk_create along with (python) list comprehension to create multiple objects.

relation "" does not exist in django for app name with mixed-case

I have faced a problem while working with django models. lets say my apps name is GasNet and my models name is Riser well the generated table name is GasNet.riser, I can successfully generate table and add objects to table and even delete all of the objects of a table. But when I try to delete an object I face this error
The above exception (relation "GasNet_riser" does not exist LINE 1: ..."."createDateTime", "GasNet_riser"."deleted" FROM "GasNet_ri... ^ ) was the direct cause of the following exception:
in debug window the sql query is as
sql
('SELECT "GasNet_riser"."id", "GasNet_riser"."city_code", '
'"GasNet_riser"."geom"::bytea, "GasNet_riser"."node_code", '
'"GasNet_riser"."pipe", "GasNet_riser"."parcel_code", '
'"GasNet_riser"."Number", "GasNet_riser"."hack", "GasNet_riser"."multi_code", '
'"GasNet_riser"."gis_code", "GasNet_riser"."angle", "GasNet_riser"."size", '
'"GasNet_riser"."direction", "GasNet_riser"."instalation_date", '
'"GasNet_riser"."description", "GasNet_riser"."type", '
'"GasNet_riser"."status", "GasNet_riser"."instalation_type", '
'"GasNet_riser"."material", "GasNet_riser"."zone_id", '
'"GasNet_riser"."prejenti_id", "GasNet_riser"."emergency_sub_zone_id", '
'"GasNet_riser"."updateDateTime", "GasNet_riser"."createDateTime", '
'"GasNet_riser"."deleted" FROM "GasNet_riser" WHERE "GasNet_riser"."id" = %s')
this is my model
class Riser(models.Model):
id=models.AutoField(primary_key=True)
city_code = models.CharField(max_length=10)
geom = models.PointField(srid=4326)
node_code = models.IntegerField(default=-1,blank=True) # شماره گره جهت اعمال مصرف آن برروی گره در طراحی
pipe = models.IntegerField(default=-1,blank=True)
parcel_code = models.IntegerField(default=-1,blank=True)
Number = models.CharField(max_length=20) #کد علمک
hack = models.IntegerField(default=-1,blank=True)
multi_code = models.CharField(max_length=10,blank=True)
gis_code = models.CharField(max_length=20,blank=True)
angle = models.FloatField(default=-1,blank=True)
size = models.IntegerField(default=-1,blank=True)
direction = models.TextField(max_length=500,blank=True)
instalation_date = models.DateField(null=True,blank=True) # تاریخ نصب
description = models.TextField(blank=True)
type = models.CharField(max_length=20,blank=True) # همان فیلد kind هست
# choises
status = models.CharField(max_length=5,default=ModelChoiseFields.NAN, choices=ModelChoiseFields.RISER_STATUS,blank=True)
instalation_type = models.CharField(max_length=5,default=ModelChoiseFields.NAN, choices=ModelChoiseFields.RISER_INSTALATION_TYPE,blank=True)
material = models.CharField(max_length=5,default=ModelChoiseFields.NAN, choices=ModelChoiseFields.RISER_MATERIAL,blank=True)
# relations
zone = models.ForeignKey(Zone,on_delete=models.CASCADE,null=True)
prejenti = models.ForeignKey(pt,models.CASCADE,null=True,blank=True)
emergency_sub_zone = models.ForeignKey(EmergencySubZone,models.CASCADE,null=True) # زیرناحیه امداد
# Auto fields
updateDateTime = models.DateTimeField('update date', auto_now_add=True, auto_now=False)
createDateTime = models.DateTimeField('create date',auto_now_add=False, auto_now=True)
deleted = models.BooleanField(default=False)
I tried makemigrations and migrate and I know that table is fine but I have no idea why this happens.
I try to delete object using this method.
selected=Riser.objects.get(id=id)
selected.delete()
I think the problem is with app name and upper case G and N but I do not know how to fix this problem.
I also tried to delete using filter and the same error happens. it says
relation "GasNet_riser" does not exist LINE 1: DELETE FROM "GasNet_riser" WHERE "GasNet_riser"."id" = 1115 ^
when I run the above query manually in my database it runse with no problem DELETE FROM "GasNet_riser" WHERE "GasNet_riser"."id" = 1115 returns Query returned successfully: one row affected, 62 msec execution time.

Odoo 8 - How to update a Many2one field value?

I'm trying to make module that gives employees visa balance.
What I'm trying to do is that when a visa number is assigned to an employee it changes the counter used_visa to be increased by 1.
so my question is how to update the counter which is in 'visa.balance.line' model when a visa number is selected in 'hr.employee' model
Here's my code:
class hr_visa_balance(models.Model):
_name = "hr.visa.balance"
_rec_name = "visa_no"
visa_no = fields.Char("Visa Number")
approval_date = fields.Date('Approval Date')
visa_line_ids = fields.One2many('visa.balance.line', 'visa_line_id', 'Visa Balance Details')
class visa_balance_line(models.Model):
_name = 'visa.balance.line'
_rec_name = "visa_line_id"
profession = fields.Char()
gender = fields.Selection([('m','Male'),('f','Female')], 'Gender')
country_id = fields.Many2one('res.country', 'Nationality')
available_visa = fields.Integer('Available')
used_visa = fields.Integer('Used')
visa_line_id = fields.Many2one('hr.visa.balance', 'Visa Balance Details')
class hr_employee(models.Model):
_inherit = 'hr.employee',
visa_line = fields.Many2one('visa.balance.line', 'Visa Balance Details')
#api.onchange('visa_line')
def onchange_visa_no(self):
~ code here ~
First of all i am not getting your structure,
i think in employee you have to choose many2one of "hr.visa.balance" object,
and you are choosing "visa.balance.line"
now what you have to do:
give one many2one of hr.visa.balance" in hr.employee and on on_change of visa_no you have to write logic,
Note: you directly can count visa balance in "hr.visa.balance" this object.
no need to take this field in visa.balance.line.