Get queryset of same multiple id's of a model in django - django

here is my models ..
class Log(models.Model):
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
date = models.DateField(default=timezone.now, blank=True, null=True)
class Logsheet(models.Model):
log = models.ForeignKey(Log, on_delete=models.CASCADE, related_name="logsheets")
driver = models.ForeignKey(Driver, on_delete=models.CASCADE, blank=True, null=True)
trip = models.IntegerField(blank=False, null=False)
distance_from = models.FloatField(blank=True, null=True, default=0.0)
distance_to = models.FloatField(blank=True, null=True, default=0.0)
time_from = models.TimeField(blank=False, null=False ,default=timezone.now)
time_to = models.TimeField(blank=False, null=False ,default=timezone.now)
source = models.CharField(max_length=100, blank=True, null=True)
destination = models.CharField(max_length=100, blank=True, null=True)
doeking_km = models.FloatField(blank=True, null=True, default=0.0)
And here is my views for creating logsheet
def create_logsheet(request):
drivers = Driver.objects.all()
vehicles = Vehicle.objects.all()
if request.method == "POST":
vehicle_id = request.POST.get("vehicle")
vehicle = Vehicle.objects.get(id=vehicle_id)
date = request.POST.get("date")
# logsheet data
trip = request.POST.getlist("trip")
time_from = request.POST.getlist("time_from")
time_to = request.POST.getlist("time_to")
source = request.POST.getlist("source")
destination = request.POST.getlist("destination")
distance_from = request.POST.getlist("distance_from")
distance_to = request.POST.getlist("distance_to")
driver_id = request.POST.getlist("driver")
driver = Driver.objects.filter(id__in=driver_id)
print(driver)
#main logic
if vehicle and driver and date:
log = Log(vehicle=vehicle, date=date)
log.save()
data = zip(trip, driver, distance_from, distance_to,time_from, time_to, source, destination)
for trip,driver, distance_from, distance_to, time_from, time_to, source, destination in data:
if trip and driver and distance_from and distance_to and time_from and time_to and source and destination:
logdetail = Logsheet(
log=log,
trip=trip,
driver=driver,
distance_from=distance_from,
distance_to=distance_to,
time_from=time_from,
time_to=time_to,
source=source,
destination=destination,
)
logdetail.save()
return redirect("logsheet_list")
Problem:
When i want same driver fro multiple trip is it not creating is return only one queryset like <QuerySet [<Driver: Mannu R>]>.
I wanted to save same driver must save from each diffrent trip.

filter returns a QuerySet. Use get instead.
driver = Driver.objects.get(id=driver_id)
And perhaps you should have a look at Django forms. This should simplify your code.

Related

How to make query to filter data from database table in Django?

There are three tables which are:
models.py
class Student(models.Model):
gen_choices = (
("Male", "Male"),
("Female", "Female"),
("Third", "Third"),
)
enrollNo = models.IntegerField(default=add_one)
fname = models.CharField(validators=[max_len_check], max_length=26)
lname = models.CharField(validators=[max_len_check], max_length=26)
gender = models.CharField(max_length=6, choices=gen_choices)
dob= models.DateField()
address = models.CharField(max_length=256)
email = models.EmailField()
mobile = models.BigIntegerField()
status = models.BooleanField(null=True)
userID = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.FileField(upload_to="stdimages/", null=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Entexaminfo(models.Model):
entexamses = (
("June Session", "June Session"),
("December Session", "December Session"),
)
approve_choice = (
("Pending", "Pending"),
("Accepted", "Accepted"),
("Rejected", "Rejected"),
)
ename = models.CharField(max_length=16, choices=entexamses)
enrollno = models.OneToOneField(Student, on_delete=models.CASCADE)
#programs = models.ManyToManyField(Programs, related_name='proNames', default=0)
program = models.ManyToManyField(Programs, default=0)
center = models.ForeignKey(Excenter, on_delete=models.CASCADE)
remarks = models.CharField(validators=[max_len_check], max_length=256, default="-")
#status = models.BooleanField()
status = models.CharField(max_length=8, choices=approve_choice, default="Pending")
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager
# for admin pannel to display for correction
def __str__(self):
return self.ename
class Ex_schedule(models.Model):
exDate = models.DateField()
exTime = models.TimeField()
exDuration = models.CharField(validators=[max_len_check], max_length=26)
programs = models.OneToOneField(Programs, on_delete=models.CASCADE)
exRemarks = models.CharField(max_length=256, null=True)
exStatus = models.BooleanField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager
# for admin pannel to display for correction
def __str__(self):
return self.exDate
class Programs(models.Model):
proName = models.CharField(validators=[max_len_check], max_length=26)
proDuration =models.CharField(validators=[max_len_check], max_length=26)
proFees = models.IntegerField(null=True)
proDetails = models.CharField(validators=[max_len_check], max_length=26, null=True)
proStatus = models.BooleanField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
objects = models.Manager
# for admin pannel to display for correction
def __str__(self):
return self.proName
I want to filter data from three tables (i.e. Student, Entexaminfo & Ex_schedule) giving a enrollno of student table, But I am not being able to filter data from Ex_schedule table because a student can choose more than one subject, according to chosen subjects data should be filter from Ex_schedule table. For this I have tried following codes but program id i have given manually, I want to replace it.
views.py
#login_required(login_url='/user/login')
def hall_ticket(request):
query = request.GET['enrollno']
if query:
entedetail = Student.objects.filter(enrollNo=query)
for obj in entedetail:
global id #To avoid 'local variable 'id' referenced before assignment' error message
id = obj.id
ent1 = Entexaminfo.objects.filter(enrollno=id)
esch = Ex_schedule.objects.filter(programs=1)
params = {'entedetails': entedetail, 'ent1': ent1, 'query': query, 'esch': esch, 'title': 'Entrance Exam Hall Ticket'}
else:
params = {'error': 'Please Enter Your Enrollment No.', 'title': 'Entrance Exam Hall Ticket'}
return render(request, 'hall_ticket.html', params)
Please guide me for it.

How to aggregate on a foreign key and a specific field at the same time?

My table named Value has a one to many relationship with the table Country and the table Output_outcome_impact. I have a query that is working fine and gets what I want but then I need to do an average of the value field, but this average needs to be done for each unique id_output_outcome_impact and not the whole query.
class Country(models.Model):
country_name = models.CharField(max_length=255, primary_key=True)
CONTINENTCHOICE = (
('Africa', 'Africa'),
('America', 'America'),
('Asia', 'Asia'),
('Europe', 'Europe'),
('Oceania', 'Oceania')
)
region = models.CharField(max_length=255)
continent = models.CharField(max_length=255, choices=CONTINENTCHOICE)
GDP_per_capita = models.IntegerField(null=True)
unemployment_rate = models.FloatField(null=True)
female_unemployment_rate = models.FloatField(null=True)
litteracy_rate = models.FloatField(null=True)
def __str__(self):
return self.country_name
class OutputOutcomeImpact(models.Model):
output_outcome_impact_name = models.CharField(max_length=255, primary_key=True)
TYPECHOICE = (
('Output', 'Output'),
('Outcome', 'Outcome'),
('Impact', 'Impact'),
)
type = models.CharField(max_length=255, choices=TYPECHOICE)
description = models.TextField()
TARGETGROUP = (
('Standard', 'Standard'),
('Investors', 'Investors'),
('Local authorities and NGOs', 'Local authorities and NGOs'),
)
target_group = models.CharField(max_length=255,choices=TARGETGROUP)
question = models.TextField(null=True, blank=True)
parent_name = models.ForeignKey('self', on_delete=models.PROTECT, null=True, blank=True)
indicator = models.ForeignKey(Indicator, on_delete=models.PROTECT)
def __str__(self):
return self.output_outcome_impact_name
class Activity(models.Model):
activity_name = models.CharField(max_length=255, primary_key=True)
description = models.TextField()
product_service = models.TextField()
output_outcome = models.TextField()
outcome_impact = models.TextField()
output_outcome_impacts = models.ManyToManyField('OutputOutcomeImpact')
countries = models.ManyToManyField('Country')
sectors = models.ManyToManyField('Sector')
def __str__(self):
return self.activity_name
class Value(models.Model):
value_name = models.CharField(max_length=255, primary_key=True)
country = models.ForeignKey(Country, on_delete=models.PROTECT)
id_output_outcome_impact = models.ForeignKey(OutputOutcomeImpact, on_delete=models.PROTECT)
value_has_source = models.ManyToManyField('Source')
value = models.FloatField()
function_name = models.CharField(max_length=255, default = "multiply")
def __str__(self):
return self.value_name
region_values = Value.objects.filter(id_output_outcome_impact__output_outcome_impact_name__in = output_pks, country_id__region = region).exclude(country_id__country_name = country).values()
So the result of the query is available below, and what I would like to achieve is to set the value field to an average of every object that has the same id_output_outcome_impact_id, here Dioxins and furans emissions reduction appears twice so I would like to get the 2 values set as their average.
<QuerySet [{'value_name': 'Waste_to_dioxins', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Dioxins and furans emissions reduction', 'value': 0.0003, 'function_name': 'multiply'}, {'value_name': 'Waste_to_dioxins_south_africa', 'country_id': 'South Africa', 'id_output_outcome_impact_id': 'Dioxins and furans emissions reduction', 'value': 150.0, 'function_name': 'multiply'}, {'value_name': 'Households getting electricity per kWh', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Households that get electricity', 'value': 0.0012, 'function_name': 'multiply'}, {'value_name': 'Dioxin to disease', 'country_id': 'Malawi', 'id_output_outcome_impact_id': 'Reduction of air pollution related diseases', 'value': 0.31, 'function_name': 'multiply'}]>
I am wondering if django models allow such modification (I went through the doc and saw the annotate function with the average but couldn't make it work for my specific case), that would be nice. Thanks.
region_values = Value.objects.filter(id_output_outcome_impact__output_outcome_impact_name__in = output_pks, country_id__region = region).exclude(country_id__country_name = country).values('id_output_outcome_impact__output_outcome_impact_name').annotate(Avg('value'))

business generated has to come based on dcr(daily call report)

I have DCR & SalesMIS model. I want to get the business generated count. And if count is it should return the business_genrated else saleMIS.amount
I wrote a method in DCR model i.e. get_business_generated(self) and apply filter on SaleMIS model. Then trying to get the count of business_generated
ERROR:D:\Projects\Python\Django\kingllp\venv\lib\site-packages\django\db\models\base.py", line 95, in new
"INSTALLED_APPS." % (module, name)
RuntimeError: Model class builtins.DCR doesn't declare an explicit app_label and isn't in an application in INSTALLED_APPS.
This is DCR model
class DCR(models.Model):
STATUSES = (
('1N', 'Need Analysis'),
('2P', 'Proposal Stage'),
('3C', 'Competitive Selling'),
('4D', 'Decision Stage'),
)
prospect = models.ForeignKey(Prospect, on_delete=models.CASCADE, related_name='dcrs')
date = models.DateField(blank=True)
status = models.CharField(choices=STATUSES, max_length=2, default='1N')
discussion_points = models.CharField(max_length=2047, blank=True)
business_generated = models.IntegerField(default=0)
is_new_business = models.BooleanField(default=False)
def get_business_generated(self):
date = self.date
client = self.prospect
sale = SalesMIS.objects.filter(date=date,client = Prospect)
salecount = sale.count()
if salecount==0:
return DCR.business_generated
else:
return SalesMIS.amount
This is SaleMIS model
class SalesMIS(models.Model):
class Meta:
verbose_name_plural = _("Sale MIS")
date = models.DateField()
fls = models.ForeignKey(Employee, blank=True, null=True, on_delete=models.SET_NULL, related_name='sales')
amount = models.DecimalField(max_digits=20, decimal_places=2)
po_number = models.CharField(max_length=255, null=True, blank=True)
products = models.CharField(max_length=255, null=True, blank=True)
client = models.ForeignKey(Client, blank=True, null=True, on_delete=models.SET_NULL, related_name='client_mis')
def __str__(self):
return str(self.date) + ":" + self.fls.full_name()
Business share has to come based on DCR/MIS.

Using django modelform for 2 instances not saving correctly

In Django 1.6.1 I have a vehicle model which might zero or up to 2 traded-in units. Every time I edit any record, whether the change is trade-in instance #1 or instance 2, both records are updated with values instance #2.
Vehicle model:
class Vehicle(models.Model):
stock = models.CharField(max_length=10, blank=False, db_index=True)
vin = models.CharField(max_length=17, blank=False, db_index=True)
#vinlast8 = models.CharField(max_length=8, blank=False, db_index=True)
make = models.CharField(max_length=15, blank=False)
model = models.CharField(max_length=15, blank=False)
year = models.CharField(max_length=4, blank=False)
registry = models.IntegerField(blank=True, verbose_name='Reg #', null=True)
plate = models.CharField(blank=True, null=True, max_length=10)
tagno = models.IntegerField(blank=True, null=True, verbose_name='Tag #')
tag_exp = models.DateField(blank=True, null=True, verbose_name='Tag Exp')
Tradein model:
class TradeIn(Vehicle):
TradeInVehicle = (
(1, 'First vehicle'),
(2, 'Second vehicle'),
)
vehicle_sale = models.ForeignKey(VehicleSale)
tradeinpos = models.IntegerField(choices=TradeInVehicle)
lienholder = models.CharField(max_length=15, blank=True, null=True, verbose_name='L/holder')
lhdocrequested = models.DateField(blank=True, null=True, verbose_name='D/Requested')
lhdocreceived = models.DateField(blank=True, null=True, verbose_name='D/Received')
class Meta:
db_table = 'tradein'
def __unicode__(self):
return self.stock
def save(self, *args, **kwargs):
self.stock = self.stock.upper()
self.vin = self.vin.upper()
return super(TradeIn, self).save(*args, **kwargs)
The related sections on view is:
These sections are related to request.GET
current_vehicle = VehicleSale.objects.get(pk=pk)
tradeIns = current_vehicle.tradein_set.all().order_by('tradeinpos')
# Also add tradein_form to t_data so it can be rendered in the template
t_count = tradeIns.count()
if t_count == 0:
t_data['tradein1_form'] = TradeInForm()
t_data['tradein2_form'] = TradeInForm()
if t_count >= 1 and tradeIns[0] and tradeIns[0].tradeinpos == 1:
t_data['tradein1_form'] = TradeInForm(instance=tradeIns[0])
t_data['tradein2_form'] = TradeInForm()
if t_count == 2 and tradeIns[1] and tradeIns[1].tradeinpos == 2:
t_data['tradein2_form'] = TradeInForm(instance=tradeIns[1])
Now these are related to request.POST:
if 'tradein-form' in request.POST:
if tradeIns.count() > 0:
if tradeIns[0]:
tradein1_form = TradeInForm(request.POST, instance=tradeIns[0])
if tradein1_form.is_valid():
tradein1_form.save()
if tradeIns[1]:
tradein2_form = TradeInForm(request.POST, instance=tradeIns[1])
if tradein2_form.is_valid():
tradein2_form.save()
While reviewing contents of request.POST, it does contain any change I make in either instance. But always, the 2nd instance is saved.
What am I missing or have wrong?

Custom Django Form

I'm trying to make a custom backend for my system and I've hit a bit of a snag....I want to give users the ability to add new makes/models/series that are not already in the system via a form. I'm wondering how I'll go about this...my models look as below:
class Manufacturer(models.Model):
MANUFACTURER_POPULARITY_CHOICES = (
('1', 'Primary'),
('2', 'Secondary'),
('3', 'Tertiary'),
)
manufacturer = models.CharField(max_length=15, blank=False)
date_added = models.DateField()
manufacturer_popularity = models.CharField(max_length=1,
choices=MANUFACTURER_POPULARITY_CHOICES)
def __unicode__(self):
return self.manufacturer
class Model(models.Model):
model = models.CharField(max_length=20, blank=False)
manufacturer = models.ForeignKey(Manufacturer)
date_added = models.DateField()
def __unicode__(self):
name = ''+str(self.manufacturer)+" "+str(self.model)
return name
class Series(models.Model):
series = models.CharField(max_length=20, blank=True, null=True)
model = models.ForeignKey(Model)
date_added = models.DateField()
def __unicode__(self):
name = str(self.model)+" "+str(self.series)
return name
class Engine(models.Model):
ENGINE_TYPE_CHOICES = (
('H', 'H'),
('I', 'I'),
('R', 'R'),
('V', 'V'),
('W', 'W'),
)
FUEL_TYPE_CHOICES = (
('G', 'Gas'),
('D', 'Diesel'),
)
size = models.DecimalField(max_digits=2, decimal_places=1)
type = models.CharField(max_length=1, choices=ENGINE_TYPE_CHOICES)
cylinders = models.PositiveSmallIntegerField()
spec = models.CharField(max_length=20, blank=True, null=True)
fuel_type = models.CharField(max_length=1, choices=FUEL_TYPE_CHOICES)
class CommonVehicle(models.Model):
year = models.ForeignKey(Year)
series = models.ForeignKey(Series)
engine = models.ForeignKey(Engine)
body_style = models.ForeignKey(BodyStyle)
transmission = models.ForeignKey(Transmission)
speeds = models.PositiveSmallIntegerField()
drive_train = models.ForeignKey(DriveTrain)
horse_power = models.PositiveSmallIntegerField()
litre_100km_city = models.DecimalField(max_digits=3, decimal_places=1)
litre_100km_hwy = models.DecimalField(max_digits=3, decimal_places=1)
def __unicode__(self):
name = ''+str(self.year)+" "+str(self.series)
return name
This seems to be a fairly standard job for a django model form. I would recommend following the documentation at http://docs.djangoproject.com/en/dev/topics/forms/modelforms/. There are detailed instructions there on how to create a form from a model and then save the returned submission to the database.