Many To Many NOT saving in django - django

my views.py file:
form = ClassesForm(request.POST)
if form.is_valid():
New_Class = Classes()
New_Class.semester = Last_Semester
New_Class.year = form.cleaned_data.get('year')
if form.cleaned_data.get('year') >= 6 and form.cleaned_data.get('year') <= 8:
New_Class.school_mode = 1
else:
New_Class.school_mode = 2
New_Class.brunch = form.cleaned_data.get('brunch')
New_Class.subject = form.cleaned_data.get('subject')
New_Class.teacher.set(Staff.objects.filter(uuid=form.cleaned_data.get('teacher').uuid))
New_Class.save()
my models.py file:
#reversion.register()
class Classes(BaseModel):
semester = models.ForeignKey(Semester, on_delete=models.PROTECT,default=get_last_semester, verbose_name=("Semester"))
school_mode = models.IntegerField(db_index=True, choices=SCHOOL_MODE, verbose_name=("School Type"))
year = models.IntegerField(db_index=True, choices=CLASS_YEARS, verbose_name=("Year"))
brunch = models.CharField(max_length=2, verbose_name=("Class Brunch"))
subject = models.CharField(max_length=15, choices=CLASS_SUBJECTS, verbose_name=("Subject"))
**teacher = models.ManyToManyField(Staff, blank=True, verbose_name=("Class Teachers"))**
class Meta:
unique_together = ('semester', 'year', 'brunch')
ordering = ['semester', 'year', 'brunch', 'subject']
def __unicode__(self):
return "%d %s %s %s / %s" % (self.semester, self.year, self.brunch, self.subject)
auditlog.register(Classes)
#reversion.register()
class Staff(BaseModel):
photo = models.ImageField(upload_to="Staff/", null=True, blank=True, verbose_name=("Photo"))
user = models.OneToOneField(User, on_delete=models.PROTECT, db_index=True, verbose_name=("User"))
name = models.CharField(max_length=30, db_index=True, verbose_name=("Name"))
surname = models.CharField(max_length=30, db_index=True, verbose_name=("Surname"))
id_no = models.CharField(max_length=15, unique=True,verbose_name=("ID Card Number"))
birthdate = models.DateField(verbose_name=("Birthdate"))
birthplace = models.CharField(max_length=30, verbose_name=("Birthplace"))
gender = models.IntegerField(choices=GENDERS, default=None, verbose_name=("Gender"))
nationality = models.CharField(choices=NATIONALITIES, max_length=20, verbose_name=("Nationality"))
blood_type = models.CharField(choices=BLOOD_TYPES, null=True, blank=True, max_length=10, verbose_name=("Blood Type"))
phone_home = models.CharField(max_length=15, null=True, blank=True, verbose_name=("Phone Home"))
phone_mobile = models.CharField(max_length=15, null=True, blank=True, verbose_name=("Phone Mobile"))
email = models.EmailField(default=None, null=True, blank=True, verbose_name=("Email Address"))
address = models.TextField(verbose_name=("Address"))
brunch = models.ForeignKey(TeacherBrunch, on_delete=models.PROTECT, verbose_name=("Brunch"))
staff_type = models.ManyToManyField(StaffType, verbose_name=("Staff Type"))
staff_status = models.IntegerField(choices=STAFF_STATUS, default=1, verbose_name=("Staff Status"))
additional_information = models.CharField(max_length=100, null=True, blank=True, verbose_name=("Additional Information"))
class Meta:
ordering = ['name', 'surname']
def __unicode__(self):
return "%s %s" % (self.name, self.surname)
def save(self, *args, **kwargs):
self.name = self.name.title()
self.surname = self.surname.upper()
self.user.save()
super(Staff, self).save(*args, **kwargs)

my views.py file:
form = ClassesForm(request.POST)
if form.is_valid():
New_Class = Classes()
New_Class.semester = Last_Semester
New_Class.year = form.cleaned_data.get('year')
if form.cleaned_data.get('year') >= 6 and form.cleaned_data.get('year') <= 8:
New_Class.school_mode = 1
else:
New_Class.school_mode = 2
New_Class.brunch = form.cleaned_data.get('brunch')
New_Class.subject = form.cleaned_data.get('subject')
New_Class.teacher.set(Staff.objects.filter(uuid=form.cleaned_data.get('teacher').uuid))
New_Class.save()
return redirect(reverse('Create-Classes'))
my model.py
class Classes(BaseModel):
semester = models.ForeignKey(Semester, on_delete=models.PROTECT,default=get_last_semester, verbose_name=_("Semester"))
school_mode = models.IntegerField(db_index=True, choices=SCHOOL_MODE, verbose_name=_("School Type"))
year = models.IntegerField(db_index=True, choices=CLASS_YEARS, verbose_name=_("Year"))
brunch = models.CharField(max_length=2, verbose_name=_("Class Brunch"))
subject = models.CharField(max_length=15, choices=CLASS_SUBJECTS, verbose_name=_("Subject"))
teacher = models.ManyToManyField(Staff, blank=True, verbose_name=_("Class Teachers"))
class Meta:
unique_together = ('semester', 'year', 'brunch')
ordering = ['semester', 'year', 'brunch', 'subject']
def __unicode__(self):
return "%d %s %s %s / %s" % (self.semester, self.year, self.brunch, self.subject)
class Staff(BaseModel):
photo = models.ImageField(upload_to="Staff/", null=True, blank=True, verbose_name=_("Photo"))
user = models.OneToOneField(User, on_delete=models.PROTECT, db_index=True, verbose_name=_("User"))
name = models.CharField(max_length=30, db_index=True, verbose_name=_("Name"))
surname = models.CharField(max_length=30, db_index=True, verbose_name=_("Surname"))
id_no = models.CharField(max_length=15, unique=True,verbose_name=_("ID Card Number"))
birthdate = models.DateField(verbose_name=_("Birthdate"))
birthplace = models.CharField(max_length=30, verbose_name=_("Birthplace"))
gender = models.IntegerField(choices=GENDERS, default=None, verbose_name=_("Gender"))
nationality = models.CharField(choices=NATIONALITIES, max_length=20, verbose_name=_("Nationality"))
blood_type = models.CharField(choices=BLOOD_TYPES, null=True, blank=True, max_length=10, verbose_name=_("Blood Type"))
phone_home = models.CharField(max_length=15, null=True, blank=True, verbose_name=_("Phone Home"))
phone_mobile = models.CharField(max_length=15, null=True, blank=True, verbose_name=_("Phone Mobile"))
email = models.EmailField(default=None, null=True, blank=True, verbose_name=_("Email Address"))
address = models.TextField(verbose_name=_("Address"))
brunch = models.ForeignKey(TeacherBrunch, on_delete=models.PROTECT, verbose_name=_("Brunch"))
staff_type = models.ManyToManyField(StaffType, verbose_name=_("Staff Type"))
staff_status = models.IntegerField(choices=STAFF_STATUS, default=1, verbose_name=_("Staff Status"))
additional_information = models.CharField(max_length=100, null=True, blank=True, verbose_name=_("Additional Information"))
class Meta:
ordering = ['name', 'surname']
def __unicode__(self):
return "%s %s" % (self.name, self.surname)
def save(self, *args, **kwargs):
self.name = self.name.title()
self.surname = self.surname.upper()
self.user.save()
super(Staff, self).save(*args, **kwargs)

Related

I want to assign a user to my card from the User table, but its not working for me

The error is:
django.db.utils.ProgrammingError: column
user_awaycardholder.assigned_user_id does not exist LINE 1:
...der"."id", "user_awaycardholder"."display_id_id", "user_away...
I am not able to create AwayCardHolder can you please tell me what is the above error ??? and How to fix that ?
class UserData(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
title = models.CharField(max_length=40, default="")
phone = models.CharField(max_length=15)
facebook_id = models.CharField(max_length=400)
youtube_id = models.CharField(max_length=400)
linkedin_id = models.CharField(max_length=400)
instagram_id = models.CharField(max_length=400)
twitter_id = models.CharField(max_length=400)
logo = models.ImageField(upload_to='logo')
profile_image = models.ImageField(upload_to='media/profile')
location = models.CharField(max_length=400)
website = models.CharField(max_length=100)
messanger = models.CharField(max_length=200)
parent_id = models.CharField(max_length=20, blank=True)
is_child = models.BooleanField(default=False)
phone_office = models.CharField(max_length=15, blank=True)
hits = models.IntegerField(max_length=10, default=0)
class Meta:
verbose_name_plural = "User Data"
def __str__(self):
name = self.user.first_name + ' ' + str(self.user.id)
return str(name)
class AwayCard(models.Model):
Away_id = models.UUIDField(default=uuid.uuid4, editable=True)
my_admin = models.ForeignKey(User, on_delete=models.CASCADE)
display_id = models.CharField(default='', max_length=30)
is_assigned = models.BooleanField(default=False)
def __str__(self):
name = str(self.display_id)
return str(name)
class AwayCardHolder(models.Model):
display_id = models.OneToOneField(AwayCard, on_delete=models.CASCADE)
assigned_user = models.ForeignKey(User, related_name="user_awaycardholder", on_delete=models.CASCADE)
def __str__(self):
name = self.display_id
return str(name)

Instance error Django Test models.py AttributeError: 'NoneType' object has no attribute

I am performing a Django test case for models.py file the models.py file looks like
import sys
from datetime import datetime
from dateutil.relativedelta import relativedelta
from django.apps import apps
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django_google_maps import fields as map_fields
from django_mysql.models import ListTextField
from simple_history.models import HistoricalRecords
from farm_management import config
from igrow.utils import get_commodity_name, get_region_name, get_farmer_name, get_variety_name
db_config = settings.USERS_DB_CONNECTION_CONFIG
class Device(models.Model):
id = models.CharField(max_length=100, primary_key=True)
fetch_status = models.BooleanField(default=True)
last_fetched_on = models.DateTimeField(auto_now=True)
geolocation = map_fields.GeoLocationField(max_length=100)
device_status = models.CharField(max_length=100, choices=config.DEVICE_STATUS, default='new')
is_active = models.BooleanField(default=True)
history = HistoricalRecords()
class Farm(models.Model):
farmer_id = models.PositiveIntegerField() # User for which farm is created
irrigation_type = models.CharField(max_length=50, choices=config.IRRIGATION_TYPE_CHOICE)
soil_test_report = models.CharField(max_length=512, null=True, blank=True)
water_test_report = models.CharField(max_length=512, null=True, blank=True)
farm_type = models.CharField(max_length=50, choices=config.FARM_TYPE_CHOICE)
franchise_type = models.CharField(max_length=50, choices=config.FRANCHISE_TYPE_CHOICE)
total_acerage = models.FloatField(help_text="In Acres", null=True, blank=True,
validators=[MaxValueValidator(1000000), MinValueValidator(0)])
farm_status = models.CharField(max_length=50, default="pipeline", choices=config.FARM_STATUS_CHOICE)
assignee_id = models.PositiveIntegerField(null=True, blank=True) # Af team user to whom farm is assigned.
previous_crop_ids = ListTextField(base_field=models.IntegerField(), null=True, blank=True, size=None)
sr_assignee_id = models.PositiveIntegerField(null=True, blank=True)
lgd_state_id = models.PositiveIntegerField(null=True, blank=True)
district_code = models.PositiveIntegerField(null=True, blank=True)
sub_district_code = models.PositiveIntegerField(null=True, blank=True)
village_code = models.PositiveIntegerField(null=True, blank=True)
farm_network_code = models.CharField(max_length=12, null=True, blank=True)
farm_health = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(0.1)],
help_text="In Percentage", null=True, blank=True)
soil_k = models.FloatField(verbose_name="Soil (K)", null=True, blank=True)
soil_n = models.FloatField(verbose_name="Soil (N)", null=True, blank=True)
soil_p = models.FloatField(verbose_name="Soil (P)", null=True, blank=True)
water_ec = models.FloatField(verbose_name="Water (ec)", null=True, blank=True)
water_ph = models.FloatField(verbose_name="Water (pH)", null=True, blank=True)
soil_test_report_date = models.DateTimeField(null=True, blank=True)
water_test_report_date = models.DateTimeField(null=True, blank=True)
pest_problems = models.TextField(verbose_name="Pest Problems (If Any)", null=True, blank=True)
onboarded_by_id = models.PositiveIntegerField(null=True, blank=True)
farm_image = models.CharField(max_length=512, null=True, blank=True)
updated_by_id = models.PositiveIntegerField(null=True, blank=True)
created_by_id = models.PositiveIntegerField(null=True, blank=True)
device_id = models.ForeignKey(Device, on_delete=models.CASCADE, related_name="farm", null=True, blank=True,
db_column='device_id')
boundary_coord = models.TextField(verbose_name="Boundary of Farm", null=True, blank=True)
lat = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
lng = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
region_name = models.CharField(max_length=200, null=True, blank=True)
farmer_name = models.CharField(max_length=200, null=True, blank=True)
farm_name = models.CharField(max_length=200, null=True, blank=True)
pending_tasks = models.PositiveIntegerField(null=True, blank=True)
batch_count = models.PositiveIntegerField(default=0, null=True, blank=True)
locality = models.CharField(max_length=200, null=True, blank=True)
history = HistoricalRecords()
class Meta:
indexes = [
models.Index(fields=['farmer_id']),
models.Index(fields=['assignee_id']),
models.Index(fields=['sr_assignee_id'])
]
def __str__(self):
return self.farm_name
def save(self, *args, **kwargs):
if self.lgd_state_id:
region_name = get_region_name(self.lgd_state_id)
if region_name:
self.region_name = region_name[0]
if self.farmer_id:
farmer_name = get_farmer_name(self.farmer_id, 'name')
if not farmer_name.empty:
self.farmer_name = farmer_name[0]
self.farm_name = "{}'s farm".format(self.farmer_name)
if self.total_acerage:
self.farm_name += " - {} acres".format(self.total_acerage)
super(Farm, self).save(*args, **kwargs)
def update_pending_tasks(self):
BatchSOPManagement = apps.get_model('sop_management', 'BatchSOPManagement')
self.pending_tasks = BatchSOPManagement.objects.filter(batch_id__farm_id=self.id, current_status=2,
due_datetime__lt=datetime.today()).count()
self.save()
def update_batch_count(self):
Batch = apps.get_model('farm_management', 'Batch')
self.batch_count = Batch.objects.filter(farm_id=self.id).count()
self.save()
def update_farm_health(self):
Batch = apps.get_model('farm_management', 'Batch')
farm_health = [batch.batch_health * batch.acerage for batch in Batch.objects.filter(farm_id=self.id) if
batch.acerage and batch.batch_health]
total_acerage = sum([batch.acerage for batch in Batch.objects.filter(farm_id=self.id) if batch.acerage])
if total_acerage:
self.farm_health = sum(farm_health) / total_acerage
self.save()
class HistoricalCropInfo(models.Model):
historical_yield_per_acre = models.FloatField(verbose_name="Yield / Acre - Historical")
commodity_id = models.PositiveIntegerField()
commodity_variety_id = models.PositiveIntegerField(null=True, blank=True)
farm_id = models.ForeignKey(Farm, on_delete=models.CASCADE, related_name="hist_crops", db_column='farm_id')
history = HistoricalRecords()
class Batch(models.Model):
commodity_id = models.PositiveIntegerField(null=True, blank=True)
commodity_variety_id = models.PositiveIntegerField(null=True, blank=True)
farm_id = models.ForeignKey(Farm, on_delete=models.CASCADE, related_name="batches", null=True, blank=True,
db_column='farm_id')
start_date = models.DateTimeField(null=True, blank=True)
acerage = models.FloatField(verbose_name='Batch Acerage', help_text="In Acres;To change this value go to farms>crop"
, validators=[MaxValueValidator(1000000), MinValueValidator(0.01)])
batch_health = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(0)],
help_text="In Percentage", default=100, null=True, blank=True)
stage = models.CharField(max_length=100, choices=config.STAGE_CHOICES, default='germination', null=True, blank=True)
expected_delivery_date = models.DateTimeField(null=True, blank=True)
current_pdd = models.FloatField(null=True, blank=True)
historic_pdd = models.FloatField(null=True, blank=True)
current_gdd = models.FloatField(null=True, blank=True)
historic_gdd = models.FloatField(null=True, blank=True)
sub_farmer_id = models.PositiveIntegerField(null=True, blank=True)
batch_status = models.CharField(max_length=100, choices=config.BATCH_STATUS, default='to_start')
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_by_id = models.PositiveIntegerField(null=True, blank=True)
created_by_id = models.PositiveIntegerField(null=True, blank=True)
historical_yield_per_acre = models.FloatField(verbose_name="Yield / Acre - Historical", null=True, blank=True)
expected_produce = models.FloatField(default=0, null=True, blank=True)
actual_produce = models.FloatField(default=0, null=True, blank=True)
sop_adherence = models.FloatField(default=0, null=True, blank=True)
actual_yield_per_acre = models.FloatField(default=0, null=True, blank=True)
end_date = models.DateTimeField(null=True, blank=True)
commodity_name = models.CharField(max_length=200, null=True, blank=True)
batch_name = models.CharField(max_length=200, null=True, blank=True)
batch_median_health = models.PositiveIntegerField(null=True, blank=True)
pending_tasks = models.PositiveIntegerField(null=True, blank=True, default=0)
history = HistoricalRecords()
def __str__(self):
return self.batch_name
def save(self, *args, **kwargs):
SOPMaster = apps.get_model('sop_management', 'SOPMaster')
BatchSOPManagement = apps.get_model('sop_management', 'BatchSOPManagement')
batch_sop_list = []
if self.batch_status is 'completed':
self.update_batch_end_date()
self.commodity_name = self.update_commodity_name()
self.batch_median_health = self.update_batch_median_health()
self.batch_name = self.update_batch_name()
super(Batch, self).save(*args, **kwargs)
def update_commodity_name(self):
if self.commodity_id:
commodity_name = get_commodity_name(self.commodity_id)
if commodity_name:
return commodity_name[0]
return None
def update_batch_median_health(self):
if self.start_date and self.expected_delivery_date:
start_date = datetime.combine(self.start_date, datetime.min.time())
expected_delivery_date = datetime.combine(self.expected_delivery_date, datetime.min.time())
end_date = min([expected_delivery_date, datetime.today()]) - relativedelta(hours=5, minutes=30)
hours_diff = int((((end_date - start_date).total_seconds()) / 3600 / 2))
median_date = start_date + relativedelta(hours=hours_diff)
try:
median_crop_health = self.history.as_of(median_date).crop_health
except:
median_crop_health = self.batch_health
return median_crop_health
else:
return None
def update_batch_name(self):
batch_name = "({}) {}".format(self.id, self.commodity_name)
if self.start_date:
batch_name += " | {}".format(self.start_date.strftime('%Y-%m-%d'))
return batch_name
def update_expected_delivery_date(self):
self.expected_delivery_date = max([batch_yield.expected_delivery_date for batch_yield in
self.batch_yields.all() if batch_yield.expected_delivery_date])
self.save()
def update_batch_status(self):
number_of_yields = self.batch_yields.all().count()
end_date_list = len([batch_yield for batch_yield in self.batch_yields.all() if
batch_yield.end_date and batch_yield.end_date.date() < datetime.today().date()])
if number_of_yields == end_date_list:
self.batch_status = 3
self.save()
def update_expected_produce(self):
self.expected_produce += sum([batch_yields.expected_production for batch_yields in self.batch_yields.all()
if not batch_yields.end_date])
self.save()
def update_actual_produce(self):
for batch_yields in self.batch_yields.all():
produce = 0
if batch_yields.grade_a_produce:
produce += batch_yields.grade_a_produce
if batch_yields.grade_b_produce:
produce += batch_yields.grade_b_produce
if batch_yields.grade_c_rejection:
produce += batch_yields.grade_c_rejection
self.actual_produce += produce
self.save()
def update_sop_adherence(self):
if self.batch_sop_management.all():
total_sop = self.batch_sop_management.filter(due_datetime__lte=datetime.today())
complete_sop = total_sop.filter(current_status=3)
if total_sop:
self.sop_adherence = complete_sop.count() / total_sop.count() * 100
self.save()
def update_actual_yield_per_acre(self):
batch_actual_produce = 0
for batch_yields in self.batch_yields.all():
actual_produce = 0
if batch_yields.end_date and batch_yields.end_date.date() <= datetime.today().date():
if batch_yields.grade_a_produce:
actual_produce += batch_yields.grade_a_produce
if batch_yields.grade_b_produce:
actual_produce += batch_yields.grade_b_produce
if batch_yields.grade_c_rejection:
actual_produce += batch_yields.grade_c_rejection
batch_actual_produce += actual_produce
if self.acerage and batch_actual_produce:
self.actual_yield_per_acre = batch_actual_produce / self.acerage
self.save()
def update_batch_end_date(self):
batch_yields = self.batch_yields.order_by('-end_date')
if batch_yields.exists():
batch_yields_id = batch_yields.filter(end_date__isnull=False)
if batch_yields_id.exists():
self.end_date = batch_yields[0].end_date
else:
self.end_date = datetime.now()
else:
raise ValidationError("Batch yield end date does not exists")
def update_pending_tasks(self):
BatchSOPManagement = apps.get_model('sop_management', 'BatchSOPManagement')
self.pending_tasks = BatchSOPManagement.objects.filter(batch_id=self.id, current_status=2,
due_datetime__lt=datetime.today()).count()
self.save()
class BatchYield(models.Model):
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_by_id = models.PositiveIntegerField(null=True, blank=True)
created_by_id = models.PositiveIntegerField(null=True, blank=True)
expected_production = models.FloatField(default=0, validators=[MaxValueValidator(1000000000), MinValueValidator(0)],
null=True, blank=True)
grade_a_produce = models.FloatField(verbose_name='Grade A - Produce', default=0, null=True, blank=True,
validators=[MaxValueValidator(1000000000), MinValueValidator(0)])
grade_b_produce = models.FloatField(verbose_name='Grade B - Produce', default=0, null=True, blank=True,
validators=[MaxValueValidator(1000000000), MinValueValidator(0)])
grade_c_rejection = models.FloatField(verbose_name='Grade C - Rejection', default=0, null=True, blank=True,
validators=[MaxValueValidator(1000000000), MinValueValidator(0)])
expected_delivery_date = models.DateTimeField()
batch_id = models.ForeignKey(Batch, on_delete=models.CASCADE, related_name="batch_yields", db_column='batch_id')
end_date = models.DateTimeField(help_text="Fill this date when this yield is realised with final date", null=True,
blank=True)
grade_a_sell_price = models.DecimalField(verbose_name='Grade A Sell Price', decimal_places=2, max_digits=7,
null=True, blank=True)
grade_b_sell_price = models.DecimalField(verbose_name='Grade B Sell Price', decimal_places=2, max_digits=7,
null=True, blank=True)
expected_grade_a_produce = models.DecimalField(decimal_places=2, max_digits=12, null=True, blank=True)
expected_grade_b_produce = models.DecimalField(decimal_places=2, max_digits=12, null=True, blank=True)
is_active = models.BooleanField(default=True)
history = HistoricalRecords()
def save(self, *args, **kwargs):
return super(BatchYield, self).save(*args, **kwargs)
def update_expected_grade_produce(self):
batch_median_health = self.batch_id.batch_median_health
if batch_median_health:
if batch_median_health == 100:
grade_a_percentage = 60
grade_b_percentage = 40
elif 90 <= batch_median_health < 100:
grade_a_percentage = 50
grade_b_percentage = 50
elif 85 <= batch_median_health < 90:
grade_a_percentage = 45
grade_b_percentage = 55
elif 80 <= batch_median_health < 85:
grade_a_percentage = 40
grade_b_percentage = 60
elif 70 <= batch_median_health < 80:
grade_a_percentage = 30
grade_b_percentage = 70
elif 65 <= batch_median_health < 70:
grade_a_percentage = 20
grade_b_percentage = 80
else:
grade_a_percentage = 0
grade_b_percentage = 100
self.expected_grade_a_produce = grade_a_percentage * self.expected_production / 100
self.expected_grade_b_produce = grade_b_percentage * self.expected_production / 100
self.save()
class batchActualProduce(models.Model):
harvest_date = models.DateField()
batch_produce = models.PositiveIntegerField(null=True, blank=True)
grade = models.CharField(max_length=10, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
batch_id = models.ForeignKey(Batch, on_delete=models.CASCADE, related_name="batch_produce", db_column='batch_id')
class Microbes(models.Model):
microbe_id = models.AutoField(primary_key=True)
product_code = models.CharField(max_length=50, unique=True)
beneficial_organism = models.TextField("beneficial_organism", null=True, blank=True)
product_nomenclature = models.TextField("product_nomenclature", null=True, blank=True)
utilization = models.TextField("uti", null=True, blank=True)
yield_increase = models.CharField(max_length=50)
savings = models.CharField(max_length=50)
fk_crop_id = models.IntegerField()
fk_region_id = models.IntegerField()
recommended_utilization = models.CharField(max_length=50, null=True, blank=True)
status = models.IntegerField(null=True, blank=True, default=True)
remedy = models.CharField(max_length=200, null=True, blank=True)
history = HistoricalRecords()
class Meta:
db_table = "microbes"
#property
def region_name(self):
"""function to return region_name based on lgd_state_id"""
if self.fk_region_id:
region_name = get_region_name(self.fk_region_id)
if region_name:
return region_name[0]
return None
#property
def commodity_name(self):
"""function to return commodity_name based on commodity_id"""
if self.fk_crop_id:
commodity_name = get_commodity_name(self.fk_crop_id)
if commodity_name:
return commodity_name[0]
return None
#property
def remedy_name(self):
"""function to return commodity_name based on commodity_id"""
remedy_name = ""
if self.remedy:
remedy_id_list = str(self.remedy).split(",")
remedy_name = ",".join(x.name for x in OrganismMapping.objects.filter(id__in=remedy_id_list))
return remedy_name
class MicrobesMapping(models.Model):
id = models.AutoField(primary_key=True)
microbe_id = models.ForeignKey(Microbes, on_delete=models.CASCADE, related_name="microbes_mapping",
db_column='microbe_id')
zone_com_microbe_id = models.CharField(max_length=200, null=True, blank=True)
remedy = models.TextField(null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(null=True, blank=True)
history = HistoricalRecords()
class OrganismMapping(models.Model):
id = models.AutoField(primary_key=True)
name = models.TextField()
status = models.IntegerField(null=True, blank=True)
history = HistoricalRecords()
class CropAttributes(models.Model):
commodity_id = models.PositiveIntegerField()
state_id = models.PositiveIntegerField()
variety_id = models.PositiveIntegerField(null=True, blank=True)
season_id = models.PositiveIntegerField(null=True, blank=True)
attribute_value = models.FloatField()
attribute_name = models.CharField(max_length=255, null=True, blank=True)
attribute_unit = models.CharField(max_length=50, null=True, blank=True)
status = models.BooleanField(default=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
#property
def commodity_name(self):
"""
function to return commodity_name based on commodity_id
"""
if self.commodity_id:
commodity_name = get_commodity_name(self.commodity_id)
if commodity_name:
return commodity_name[0]
return None
#property
def state_name(self):
"""
function to return region_name based on lgd_state_id
"""
if self.state_id:
state_name = get_region_name(self.state_id)
if state_name:
return state_name[0]
return None
#property
def variety_name(self):
"""
function to return variety_name based on variety_id
"""
if self.variety_id:
variety_name = get_variety_name(self.variety_id)
if variety_name:
return variety_name[0]
return None
class CropAttributesMaster(models.Model):
name = models.CharField(max_length=255, null=True, blank=True)
unit = models.CharField(max_length=50, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
#receiver([post_save, post_delete], sender=BatchYield)
def expected_delivery_date_update(sender, instance, **kwargs):
try:
sys.setrecursionlimit(120)
instance.batch_id.update_expected_delivery_date()
instance.batch_id.update_batch_status()
# instance.batch_id.update_expected_produce()
instance.batch_id.update_actual_produce()
instance.batch_id.update_sop_adherence()
instance.batch_id.update_actual_yield_per_acre()
instance.update_expected_grade_produce()
except:
pass
#receiver([post_save, post_delete], sender=Batch)
def update_batch_count(sender, instance, **kwargs):
instance.farm_id.update_batch_count()
#receiver(post_save, sender=Batch)
def update_farm_health(sender, instance, **kwargs):
instance.farm_id.update_farm_health()
for models.py file first I am testing the Batch class
in test_batch.py file which looks like
from datetime import datetime
from django import apps
from django.dispatch import receiver
from django.test import TestCase
from django.db.utils import IntegrityError
from django.db.models.signals import post_save, post_delete
from farm_management.models import Farm, Device, BatchYield, Batch
from sop_management.models import BatchSOPManagement
class TestBatch(TestCase):
def setUp(self):
self.batch1 = Batch.objects.create(
batch_name="(907) Cucumber | 2021-08-21",
acerage="4",
commodity_name="Cucumber"
)
self.farm_id = Farm.objects.create(farmer_id="106", batch_count="1")
def test_update_batch_name(self):
for i in range(5):
Batch.objects.create(farm_id=self.farm_id, commodity_name="Cucumber")
self.batch1.update_batch_name()
assert self.batch1.batch_name == 5
def test_batch(self):
self.assertEqual(self.batch1.batch_name, "(907) Cucumber | 2021-08-21")
self.assertEqual(self.batch1.acerage, "4")
self.assertEqual(self.farm_id.farmer_id, "106")
self.assertEqual(self.batch1.commodity_name, "Cucumber")
def test_return(self):
batch11 = Batch.objects.create(batch_name="(907) Cucumber | 2021-08-21", acerage="4")
batch11.save()
self.assertEqual(str(batch11), "(907) Cucumber | 2021-08-21")
def test_batch_count(self):
for i in range(1):
Batch.objects.create(farm_id=self.farm_id, acerage="4")
self.batch1.update_batch_count()
assert self.batch1.batch_count == 1
while performing the testing of batch class everytime I am getting the same error
the error looks
ERROR: test_update_batch_name (farm_management.test.models.test_batch.TestBatch)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/admin123/igrow-api/app/farm_management/test/models/test_batch.py", line 14, in setUp
self.batch1 = Batch.objects.create(
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/query.py", line 453, in create
obj.save(force_insert=True, using=self.db)
File "/home/admin123/igrow-api/app/farm_management/models.py", line 179, in save
super(Batch, self).save(*args, **kwargs)
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/base.py", line 774, in save_base
post_save.send(
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
return [
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 181, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/home/admin123/igrow-api/app/farm_management/models.py", line 482, in update_batch_count
instance.farm_id.update_batch_count()
AttributeError: 'NoneType' object has no attribute 'update_batch_count'
----------------------------------------------------------------------
Ran 1 test in 0.007s
FAILED (errors=1)
Destroying test database for alias 'default'...

Django testinng of models.py foreign key error

I am testing the testing the models.py file which contain two class one is Farm and another one is Batch
and Batch has a foreign key related to farm
while testing the batch I have tested all the other columns but not sure how should I test the foreign key column of batch class
models.py file lopoks like
import sys
from datetime import datetime
from dateutil.relativedelta import relativedelta
from django.apps import apps
from django.conf import settings
from django.core.exceptions import ValidationError
from django.core.validators import MaxValueValidator, MinValueValidator
from django.db import models
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django_google_maps import fields as map_fields
from django_mysql.models import ListTextField
from simple_history.models import HistoricalRecords
from farm_management import config
from igrow.utils import get_commodity_name, get_region_name, get_farmer_name, get_variety_name
db_config = settings.USERS_DB_CONNECTION_CONFIG
class Device(models.Model):
id = models.CharField(max_length=100, primary_key=True)
fetch_status = models.BooleanField(default=True)
last_fetched_on = models.DateTimeField(auto_now=True)
geolocation = map_fields.GeoLocationField(max_length=100)
device_status = models.CharField(max_length=100, choices=config.DEVICE_STATUS, default='new')
is_active = models.BooleanField(default=True)
history = HistoricalRecords()
class Farm(models.Model):
farmer_id = models.PositiveIntegerField() # User for which farm is created
irrigation_type = models.CharField(max_length=50, choices=config.IRRIGATION_TYPE_CHOICE)
soil_test_report = models.CharField(max_length=512, null=True, blank=True)
water_test_report = models.CharField(max_length=512, null=True, blank=True)
farm_type = models.CharField(max_length=50, choices=config.FARM_TYPE_CHOICE)
franchise_type = models.CharField(max_length=50, choices=config.FRANCHISE_TYPE_CHOICE)
total_acerage = models.FloatField(help_text="In Acres", null=True, blank=True,
validators=[MaxValueValidator(1000000), MinValueValidator(0)])
farm_status = models.CharField(max_length=50, default="pipeline", choices=config.FARM_STATUS_CHOICE)
assignee_id = models.PositiveIntegerField(null=True, blank=True) # Af team user to whom farm is assigned.
previous_crop_ids = ListTextField(base_field=models.IntegerField(), null=True, blank=True, size=None)
sr_assignee_id = models.PositiveIntegerField(null=True, blank=True)
lgd_state_id = models.PositiveIntegerField(null=True, blank=True)
district_code = models.PositiveIntegerField(null=True, blank=True)
sub_district_code = models.PositiveIntegerField(null=True, blank=True)
village_code = models.PositiveIntegerField(null=True, blank=True)
farm_network_code = models.CharField(max_length=12, null=True, blank=True)
farm_health = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(0.1)],
help_text="In Percentage", null=True, blank=True)
soil_k = models.FloatField(verbose_name="Soil (K)", null=True, blank=True)
soil_n = models.FloatField(verbose_name="Soil (N)", null=True, blank=True)
soil_p = models.FloatField(verbose_name="Soil (P)", null=True, blank=True)
water_ec = models.FloatField(verbose_name="Water (ec)", null=True, blank=True)
water_ph = models.FloatField(verbose_name="Water (pH)", null=True, blank=True)
soil_test_report_date = models.DateTimeField(null=True, blank=True)
water_test_report_date = models.DateTimeField(null=True, blank=True)
pest_problems = models.TextField(verbose_name="Pest Problems (If Any)", null=True, blank=True)
onboarded_by_id = models.PositiveIntegerField(null=True, blank=True)
farm_image = models.CharField(max_length=512, null=True, blank=True)
updated_by_id = models.PositiveIntegerField(null=True, blank=True)
created_by_id = models.PositiveIntegerField(null=True, blank=True)
device_id = models.ForeignKey(Device, on_delete=models.CASCADE, related_name="farm", null=True, blank=True,
db_column='device_id')
boundary_coord = models.TextField(verbose_name="Boundary of Farm", null=True, blank=True)
lat = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
lng = models.DecimalField(max_digits=22, decimal_places=16, blank=True, null=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
is_active = models.BooleanField(default=True)
region_name = models.CharField(max_length=200, null=True, blank=True)
farmer_name = models.CharField(max_length=200, null=True, blank=True)
farm_name = models.CharField(max_length=200, null=True, blank=True)
pending_tasks = models.PositiveIntegerField(null=True, blank=True)
batch_count = models.PositiveIntegerField(default=0, null=True, blank=True)
locality = models.CharField(max_length=200, null=True, blank=True)
history = HistoricalRecords()
class Meta:
indexes = [
models.Index(fields=['farmer_id']),
models.Index(fields=['assignee_id']),
models.Index(fields=['sr_assignee_id'])
]
def __str__(self):
return self.farm_name
def save(self, *args, **kwargs):
if self.lgd_state_id:
region_name = get_region_name(self.lgd_state_id)
if region_name:
self.region_name = region_name[0]
if self.farmer_id:
farmer_name = get_farmer_name(self.farmer_id, 'name')
if not farmer_name.empty:
self.farmer_name = farmer_name[0]
self.farm_name = "{}'s farm".format(self.farmer_name)
if self.total_acerage:
self.farm_name += " - {} acres".format(self.total_acerage)
super(Farm, self).save(*args, **kwargs)
def update_pending_tasks(self):
BatchSOPManagement = apps.get_model('sop_management', 'BatchSOPManagement')
self.pending_tasks = BatchSOPManagement.objects.filter(batch_id__farm_id=self.id, current_status=2,
due_datetime__lt=datetime.today()).count()
self.save()
def update_batch_count(self):
Batch = apps.get_model('farm_management', 'Batch')
self.batch_count = Batch.objects.filter(farm_id=self.id).count()
self.save()
def update_farm_health(self):
Batch = apps.get_model('farm_management', 'Batch')
farm_health = [batch.batch_health * batch.acerage for batch in Batch.objects.filter(farm_id=self.id) if
batch.acerage and batch.batch_health]
total_acerage = sum([batch.acerage for batch in Batch.objects.filter(farm_id=self.id) if batch.acerage])
if total_acerage:
self.farm_health = sum(farm_health) / total_acerage
self.save()
class HistoricalCropInfo(models.Model):
historical_yield_per_acre = models.FloatField(verbose_name="Yield / Acre - Historical")
commodity_id = models.PositiveIntegerField()
commodity_variety_id = models.PositiveIntegerField(null=True, blank=True)
farm_id = models.ForeignKey(Farm, on_delete=models.CASCADE, related_name="hist_crops", db_column='farm_id')
history = HistoricalRecords()
class Batch(models.Model):
commodity_id = models.PositiveIntegerField(null=True, blank=True)
commodity_variety_id = models.PositiveIntegerField(null=True, blank=True)
farm_id = models.ForeignKey(Farm, on_delete=models.CASCADE, related_name="batches", null=True, blank=True,
db_column='farm_id')
start_date = models.DateTimeField(null=True, blank=True)
acerage = models.FloatField(verbose_name='Batch Acerage', help_text="In Acres;To change this value go to farms>crop"
, validators=[MaxValueValidator(1000000), MinValueValidator(0.01)])
batch_health = models.IntegerField(validators=[MaxValueValidator(100), MinValueValidator(0)],
help_text="In Percentage", default=100, null=True, blank=True)
stage = models.CharField(max_length=100, choices=config.STAGE_CHOICES, default='germination', null=True, blank=True)
expected_delivery_date = models.DateTimeField(null=True, blank=True)
current_pdd = models.FloatField(null=True, blank=True)
historic_pdd = models.FloatField(null=True, blank=True)
current_gdd = models.FloatField(null=True, blank=True)
historic_gdd = models.FloatField(null=True, blank=True)
sub_farmer_id = models.PositiveIntegerField(null=True, blank=True)
batch_status = models.CharField(max_length=100, choices=config.BATCH_STATUS, default='to_start')
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_by_id = models.PositiveIntegerField(null=True, blank=True)
created_by_id = models.PositiveIntegerField(null=True, blank=True)
historical_yield_per_acre = models.FloatField(verbose_name="Yield / Acre - Historical", null=True, blank=True)
expected_produce = models.FloatField(default=0, null=True, blank=True)
actual_produce = models.FloatField(default=0, null=True, blank=True)
sop_adherence = models.FloatField(default=0, null=True, blank=True)
actual_yield_per_acre = models.FloatField(default=0, null=True, blank=True)
end_date = models.DateTimeField(null=True, blank=True)
commodity_name = models.CharField(max_length=200, null=True, blank=True)
batch_name = models.CharField(max_length=200, null=True, blank=True)
batch_median_health = models.PositiveIntegerField(null=True, blank=True)
pending_tasks = models.PositiveIntegerField(null=True, blank=True, default=0)
history = HistoricalRecords()
def __str__(self):
return self.batch_name
def save(self, *args, **kwargs):
SOPMaster = apps.get_model('sop_management', 'SOPMaster')
BatchSOPManagement = apps.get_model('sop_management', 'BatchSOPManagement')
batch_sop_list = []
if self.batch_status is 'completed':
self.update_batch_end_date()
self.commodity_name = self.update_commodity_name()
self.batch_median_health = self.update_batch_median_health()
self.batch_name = self.update_batch_name()
super(Batch, self).save(*args, **kwargs)
def update_commodity_name(self):
if self.commodity_id:
commodity_name = get_commodity_name(self.commodity_id)
if commodity_name:
return commodity_name[0]
return None
def update_batch_median_health(self):
if self.start_date and self.expected_delivery_date:
start_date = datetime.combine(self.start_date, datetime.min.time())
expected_delivery_date = datetime.combine(self.expected_delivery_date, datetime.min.time())
end_date = min([expected_delivery_date, datetime.today()]) - relativedelta(hours=5, minutes=30)
hours_diff = int((((end_date - start_date).total_seconds()) / 3600 / 2))
median_date = start_date + relativedelta(hours=hours_diff)
try:
median_crop_health = self.history.as_of(median_date).crop_health
except:
median_crop_health = self.batch_health
return median_crop_health
else:
return None
def update_batch_name(self):
batch_name = "({}) {}".format(self.id, self.commodity_name)
if self.start_date:
batch_name += " | {}".format(self.start_date.strftime('%Y-%m-%d'))
return batch_name
def update_expected_delivery_date(self):
self.expected_delivery_date = max([batch_yield.expected_delivery_date for batch_yield in
self.batch_yields.all() if batch_yield.expected_delivery_date])
self.save()
def update_batch_status(self):
number_of_yields = self.batch_yields.all().count()
end_date_list = len([batch_yield for batch_yield in self.batch_yields.all() if
batch_yield.end_date and batch_yield.end_date.date() < datetime.today().date()])
if number_of_yields == end_date_list:
self.batch_status = 3
self.save()
def update_expected_produce(self):
self.expected_produce += sum([batch_yields.expected_production for batch_yields in self.batch_yields.all()
if not batch_yields.end_date])
self.save()
def update_actual_produce(self):
for batch_yields in self.batch_yields.all():
produce = 0
if batch_yields.grade_a_produce:
produce += batch_yields.grade_a_produce
if batch_yields.grade_b_produce:
produce += batch_yields.grade_b_produce
if batch_yields.grade_c_rejection:
produce += batch_yields.grade_c_rejection
self.actual_produce += produce
self.save()
def update_sop_adherence(self):
if self.batch_sop_management.all():
total_sop = self.batch_sop_management.filter(due_datetime__lte=datetime.today())
complete_sop = total_sop.filter(current_status=3)
if total_sop:
self.sop_adherence = complete_sop.count() / total_sop.count() * 100
self.save()
def update_actual_yield_per_acre(self):
batch_actual_produce = 0
for batch_yields in self.batch_yields.all():
actual_produce = 0
if batch_yields.end_date and batch_yields.end_date.date() <= datetime.today().date():
if batch_yields.grade_a_produce:
actual_produce += batch_yields.grade_a_produce
if batch_yields.grade_b_produce:
actual_produce += batch_yields.grade_b_produce
if batch_yields.grade_c_rejection:
actual_produce += batch_yields.grade_c_rejection
batch_actual_produce += actual_produce
if self.acerage and batch_actual_produce:
self.actual_yield_per_acre = batch_actual_produce / self.acerage
self.save()
def update_batch_end_date(self):
batch_yields = self.batch_yields.order_by('-end_date')
if batch_yields.exists():
batch_yields_id = batch_yields.filter(end_date__isnull=False)
if batch_yields_id.exists():
self.end_date = batch_yields[0].end_date
else:
self.end_date = datetime.now()
else:
raise ValidationError("Batch yield end date does not exists")
def update_pending_tasks(self):
BatchSOPManagement = apps.get_model('sop_management', 'BatchSOPManagement')
self.pending_tasks = BatchSOPManagement.objects.filter(batch_id=self.id, current_status=2,
due_datetime__lt=datetime.today()).count()
self.save()
class BatchYield(models.Model):
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_by_id = models.PositiveIntegerField(null=True, blank=True)
created_by_id = models.PositiveIntegerField(null=True, blank=True)
expected_production = models.FloatField(default=0, validators=[MaxValueValidator(1000000000), MinValueValidator(0)],
null=True, blank=True)
grade_a_produce = models.FloatField(verbose_name='Grade A - Produce', default=0, null=True, blank=True,
validators=[MaxValueValidator(1000000000), MinValueValidator(0)])
grade_b_produce = models.FloatField(verbose_name='Grade B - Produce', default=0, null=True, blank=True,
validators=[MaxValueValidator(1000000000), MinValueValidator(0)])
grade_c_rejection = models.FloatField(verbose_name='Grade C - Rejection', default=0, null=True, blank=True,
validators=[MaxValueValidator(1000000000), MinValueValidator(0)])
expected_delivery_date = models.DateTimeField()
batch_id = models.ForeignKey(Batch, on_delete=models.CASCADE, related_name="batch_yields", db_column='batch_id')
end_date = models.DateTimeField(help_text="Fill this date when this yield is realised with final date", null=True,
blank=True)
grade_a_sell_price = models.DecimalField(verbose_name='Grade A Sell Price', decimal_places=2, max_digits=7,
null=True, blank=True)
grade_b_sell_price = models.DecimalField(verbose_name='Grade B Sell Price', decimal_places=2, max_digits=7,
null=True, blank=True)
expected_grade_a_produce = models.DecimalField(decimal_places=2, max_digits=12, null=True, blank=True)
expected_grade_b_produce = models.DecimalField(decimal_places=2, max_digits=12, null=True, blank=True)
is_active = models.BooleanField(default=True)
history = HistoricalRecords()
def save(self, *args, **kwargs):
return super(BatchYield, self).save(*args, **kwargs)
def update_expected_grade_produce(self):
batch_median_health = self.batch_id.batch_median_health
if batch_median_health:
if batch_median_health == 100:
grade_a_percentage = 60
grade_b_percentage = 40
elif 90 <= batch_median_health < 100:
grade_a_percentage = 50
grade_b_percentage = 50
elif 85 <= batch_median_health < 90:
grade_a_percentage = 45
grade_b_percentage = 55
elif 80 <= batch_median_health < 85:
grade_a_percentage = 40
grade_b_percentage = 60
elif 70 <= batch_median_health < 80:
grade_a_percentage = 30
grade_b_percentage = 70
elif 65 <= batch_median_health < 70:
grade_a_percentage = 20
grade_b_percentage = 80
else:
grade_a_percentage = 0
grade_b_percentage = 100
self.expected_grade_a_produce = grade_a_percentage * self.expected_production / 100
self.expected_grade_b_produce = grade_b_percentage * self.expected_production / 100
self.save()
class batchActualProduce(models.Model):
harvest_date = models.DateField()
batch_produce = models.PositiveIntegerField(null=True, blank=True)
grade = models.CharField(max_length=10, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
batch_id = models.ForeignKey(Batch, on_delete=models.CASCADE, related_name="batch_produce", db_column='batch_id')
class Microbes(models.Model):
microbe_id = models.AutoField(primary_key=True)
product_code = models.CharField(max_length=50, unique=True)
beneficial_organism = models.TextField("beneficial_organism", null=True, blank=True)
product_nomenclature = models.TextField("product_nomenclature", null=True, blank=True)
utilization = models.TextField("uti", null=True, blank=True)
yield_increase = models.CharField(max_length=50)
savings = models.CharField(max_length=50)
fk_crop_id = models.IntegerField()
fk_region_id = models.IntegerField()
recommended_utilization = models.CharField(max_length=50, null=True, blank=True)
status = models.IntegerField(null=True, blank=True, default=True)
remedy = models.CharField(max_length=200, null=True, blank=True)
history = HistoricalRecords()
class Meta:
db_table = "microbes"
#property
def region_name(self):
"""function to return region_name based on lgd_state_id"""
if self.fk_region_id:
region_name = get_region_name(self.fk_region_id)
if region_name:
return region_name[0]
return None
#property
def commodity_name(self):
"""function to return commodity_name based on commodity_id"""
if self.fk_crop_id:
commodity_name = get_commodity_name(self.fk_crop_id)
if commodity_name:
return commodity_name[0]
return None
#property
def remedy_name(self):
"""function to return commodity_name based on commodity_id"""
remedy_name = ""
if self.remedy:
remedy_id_list = str(self.remedy).split(",")
remedy_name = ",".join(x.name for x in OrganismMapping.objects.filter(id__in=remedy_id_list))
return remedy_name
class MicrobesMapping(models.Model):
id = models.AutoField(primary_key=True)
microbe_id = models.ForeignKey(Microbes, on_delete=models.CASCADE, related_name="microbes_mapping",
db_column='microbe_id')
zone_com_microbe_id = models.CharField(max_length=200, null=True, blank=True)
remedy = models.TextField(null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
status = models.IntegerField(null=True, blank=True)
history = HistoricalRecords()
class OrganismMapping(models.Model):
id = models.AutoField(primary_key=True)
name = models.TextField()
status = models.IntegerField(null=True, blank=True)
history = HistoricalRecords()
class CropAttributes(models.Model):
commodity_id = models.PositiveIntegerField()
state_id = models.PositiveIntegerField()
variety_id = models.PositiveIntegerField(null=True, blank=True)
season_id = models.PositiveIntegerField(null=True, blank=True)
attribute_value = models.FloatField()
attribute_name = models.CharField(max_length=255, null=True, blank=True)
attribute_unit = models.CharField(max_length=50, null=True, blank=True)
status = models.BooleanField(default=True, null=True, blank=True)
updated_at = models.DateTimeField(auto_now=True)
created_at = models.DateTimeField(auto_now_add=True)
#property
def commodity_name(self):
"""
function to return commodity_name based on commodity_id
"""
if self.commodity_id:
commodity_name = get_commodity_name(self.commodity_id)
if commodity_name:
return commodity_name[0]
return None
#property
def state_name(self):
"""
function to return region_name based on lgd_state_id
"""
if self.state_id:
state_name = get_region_name(self.state_id)
if state_name:
return state_name[0]
return None
#property
def variety_name(self):
"""
function to return variety_name based on variety_id
"""
if self.variety_id:
variety_name = get_variety_name(self.variety_id)
if variety_name:
return variety_name[0]
return None
class CropAttributesMaster(models.Model):
name = models.CharField(max_length=255, null=True, blank=True)
unit = models.CharField(max_length=50, null=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True)
#receiver([post_save, post_delete], sender=BatchYield)
def expected_delivery_date_update(sender, instance, **kwargs):
try:
sys.setrecursionlimit(120)
instance.batch_id.update_expected_delivery_date()
instance.batch_id.update_batch_status()
# instance.batch_id.update_expected_produce()
instance.batch_id.update_actual_produce()
instance.batch_id.update_sop_adherence()
instance.batch_id.update_actual_yield_per_acre()
instance.update_expected_grade_produce()
except:
pass
#receiver([post_save, post_delete], sender=Batch)
def update_batch_count(sender, instance, **kwargs):
instance.farm_id.update_batch_count()
#receiver(post_save, sender=Batch)
def update_farm_health(sender, instance, **kwargs):
instance.farm_id.update_farm_health()
and the class that i am tersting right now is Batch
and test file of batch looks like
from django.test import TestCase
from django.db.utils import IntegrityError
from farm_management.models import Farm, Device, BatchYield, Batch
class TestBatch(TestCase):
def setUp(self):
self.batch1 = Batch.objects.create(
commodity_id="2",
commodity_variety_id="4",
acerage="90",
batch_health="100",
stage="germination",
batch_status="running",
updated_at="2021-11-26 09:27:18.464511",
created_at="2021-11-26 08:50:26.618932",
updated_by_id="1224",
created_by_id="1224",
#batch_name="(1) Apple | 2021-11-26",
commodity_name="Apple",
#start_date="2021-11-26 14:20:14.000000"
)
self.farmid = Farm.objects.get(farmer_id="1")
def test_farm(self):
self.assertEqual(self.batch1.commodity_id, "2")
self.assertEqual(self.batch1.commodity_variety_id, "4")
self.assertEqual(self.batch1.acerage, "90")
self.assertEqual(self.batch1.batch_health, "100")
self.assertEqual(self.batch1.stage, "germination")
self.assertEqual(self.batch1.batch_status, "running")
self.assertEqual(self.batch1.updated_at, "2021-11-26 09:27:18.464511")
self.assertEqual(self.batch1.created_at, "2021-11-26 08:50:26.618932")
self.assertEqual(self.batch1.updated_by_id, "1224")
self.assertEqual(self.batch1.created_by_id, "1224")
self.assertEqual(self.batch1.batch_name, "(1) Apple | 2021-11-26")
self.assertEqual(self.batch1.commodity_name, "Apple")
self.assertEqual(self.batch1.start_date, "2021-11-26 14:20:14.000000")
self.assertEqual((self.farmid.farmer_id, "1"))
But this testing code giving error
/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/storages/backends/s3boto3.py:282: UserWarning: The default behavior of S3Boto3Storage is insecure and will change in django-storages 2.0. By default files and new buckets are saved with an ACL of 'public-read' (globally publicly readable). Version 2.0 will default to using the bucket's ACL. To opt into the new behavior set AWS_DEFAULT_ACL = None, otherwise to silence this warning explicitly set AWS_DEFAULT_ACL.
warnings.warn(
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
E
======================================================================
ERROR: test_farm (farm_management.test.models.batch.TestBatch)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/admin123/igrow-api/app/farm_management/test/models/batch.py", line 10, in setUp
self.batch1 = Batch.objects.create(
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/manager.py", line 85, in manager_method
return getattr(self.get_queryset(), name)(*args, **kwargs)
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/query.py", line 453, in create
obj.save(force_insert=True, using=self.db)
File "/home/admin123/igrow-api/app/farm_management/models.py", line 179, in save
super(Batch, self).save(*args, **kwargs)
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/base.py", line 726, in save
self.save_base(using=using, force_insert=force_insert,
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/db/models/base.py", line 774, in save_base
post_save.send(
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 180, in send
return [
File "/home/admin123/igrow-api/igrow-api-backend/lib/python3.8/site-packages/django/dispatch/dispatcher.py", line 181, in <listcomp>
(receiver, receiver(signal=self, sender=sender, **named))
File "/home/admin123/igrow-api/app/farm_management/models.py", line 482, in update_batch_count
instance.farm_id.update_batch_count()
AttributeError: 'NoneType' object has no attribute 'update_batch_count'
----------------------------------------------------------------------
Ran 1 test in 0.527s
FAILED (errors=1)
Destroying test database for alias 'default'...
and update_batch_count is in farm class
def update_batch_count(self):
Batch = apps.get_model('farm_management', 'Batch')
self.batch_count = Batch.objects.filter(farm_id=self.id).count()
self.save()
and bacth_count is a column of fram class

'DemoAppProductUpdateDestroySerializer' object has no attribute 'get_image'

'DemoAppProductUpdateDestroySerializer' object has no attribute 'get_image'.
i am getting error on 'DemoAppProductUpdateDestroySerializer' object has no attribute 'get_image'. any help, would be appreciated.
'DemoAppProductUpdateDestroySerializer' object has no attribute
'get_image'
models.py
class Product(models.Model):
title = models.CharField(max_length=30)
slug= models.SlugField(blank=True, null=True)
sku = models.CharField(max_length=30)
description = models.TextField(max_length=200, null=True, blank=True)
instruction = models.TextField(max_length=200, null=True, blank=True)
price = models.DecimalField(decimal_places=2, max_digits= 10,)
discount_price= models.DecimalField(decimal_places=2, max_digits= 10, null=True, blank=True)
brand = models.ForeignKey("Brand", null=True, blank=True, on_delete=models.CASCADE)
waist = models.ForeignKey("Waist", null=True, blank=True, on_delete=models.CASCADE)
occasion = models.ForeignKey("Occasion", null=True, blank=True, on_delete=models.CASCADE)
style = models.ForeignKey("Style", null=True, blank=True, on_delete=models.CASCADE)
neck = models.ForeignKey("Neck", null=True, blank=True, on_delete=models.CASCADE)
fit = models.ForeignKey("Fit", null=True, blank=True, on_delete=models.CASCADE)
pattern_type = models.ForeignKey("Pattern_Type", null=True, blank=True, on_delete=models.CASCADE)
color = models.ForeignKey("Color", null=True, blank=True, on_delete=models.CASCADE)
size = models.ManyToManyField("Size", null=True, blank=True)
sleeve = models.ForeignKey("Sleeve_Length", null=True, blank=True, on_delete=models.CASCADE)
material = models.ForeignKey("Material", null=True, blank=True, on_delete=models.CASCADE)
category = models.ManyToManyField('Category', )
default = models.ForeignKey('Category', related_name='default_category', null=True, blank=True, on_delete=models.CASCADE)
created_on = models.DateTimeField(default=timezone.now)
updated_on = models.DateTimeField(null=True, blank=True)
status = models.BooleanField(default=True)
class Meta:
ordering = ["-id"]
def __str__(self): #def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("product_detail", kwargs={"pk": self.pk})
def get_image_url(self):
img = self.productimage_set.first()
if img:
return img.image.url
return img #None
def pre_save_post_receiver(sender, instance, *args, **kwargs):
if not instance.slug:
instance.slug = unique_slug_generator(instance)
pre_save.connect(pre_save_post_receiver, sender=Product)
def image_upload_to(instance, filename):
title = instance.product.title
slug = slugify(title)
basename, file_extension = filename.split(".")
new_filename = "%s-%s.%s" %(slug, instance.id, file_extension)
return "products/%s/%s" %(slug, new_filename)
class ProductImage(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
image = models.ImageField(upload_to=image_upload_to)
created_on = models.DateTimeField(default=timezone.now)
status = models.BooleanField(default=True)
def __unicode__(self):
return self.product.title
views.py
class ProductUpdateDestroyAPIView(generics.RetrieveUpdateDestroyAPIView):
model = Product
queryset = Product.objects.all()
serializer_class = DemoAppProductUpdateDestroySerializer
permission_classes = [IsAdminUser]
authentication_classes = [BasicAuthentication]
serializers.py
class DemoAppProductUpdateDestroySerializer(serializers.ModelSerializer):
image = serializers.SerializerMethodField()
class Meta:
model = Product
fields=[
"id",
"title",
"slug",
"sku",
"price",
"discount_price",
"image",
]
def get_image(self, obj):
return obj.productimage_set.first().image.url

How to take array of foreign keys in django model

I have a model product , price and custorder. I want a list of products while creating the order which is used as a foreign key in custorder. I am using postgres as database.
class Product(models.Model):
product = ArrayField(models.CharField(max_length=200), blank=True)
def __str__(self):
return str(self.product)
class Price(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
price = models.DecimalField(max_digits=50, decimal_places = 5, default=0)
def __str__(self):
return "%s" % self.price
class CustOrder(models.Model):
Customer_id = models.AutoField(primary_key=True)
CustomerName = models.CharField(max_length=200)
email = models.EmailField(max_length=70,blank=True, null= True, unique= True)
gender = models.CharField(max_length=6, choices=GENDER_CHOICES)
phone = PhoneField(null=False, blank=True, unique=True)
landmark = models.PointField()
#landmark = models.TextField(max_length=400, help_text="Enter the landmark", default='Enter landmark')
houseno = models.IntegerField(default=0)
#product_name = models.CharField(max_length=200, choices=PRODUCT_CHOICES,default='Boneless chicken')
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True,related_name='pricetag')
quantity = models.IntegerField(default=0)
price = models.ForeignKey(Price, on_delete=models.SET_NULL, null=True,related_name='pricetag')
#price = models.DecimalField(max_digits=50, decimal_places=5, default=48.9)
pay_method = models.CharField(max_length=200,choices=PAYMENT_CHOICES, default='RAZOR PAY')
city = models.ForeignKey(City, on_delete=models.SET_NULL, null=True)
area = models.ForeignKey(Area, on_delete=models.SET_NULL, null=True)
Price.objects.aggregate(Sum('price'))
def __str__(self):
return self.CustomerName