getting the pk of other model from one model - django

models.py
class Customer(models.Model):
customer_name = models.CharField(max_length=50)
address = models.CharField(max_length=100)
bill_no = models.CharField(max_length=8)
class Sell(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
date = models.DateField(auto_now_add=True)
total = models.IntegerField()
vat = models.IntegerField()
How do get the customer id from Sell model/object?
like Sell.objects.get(pk=..)

You can get using foreign key concept.
Here you can get the pk of Customer model using customer field of Sell model, it will be customer__pk.
Similarly customer_name you can get by customer__customer_name and address using customer__address and bill_no using customer__bill_no.
Note: Remember it is fieldnameincurrentmodel__othermodelfieldname, it is the double underscore.
Sell.objects.get(pk=customer__pk)

Related

How to change field value dynamically depended on dropdown selection in django

I've been searching Google, but couldn't find a simple answer to this problem:
I have a django models that stores students information and three other models like this:
class Level(models.Model):
name = models.CharField(max_length=50)
class Pricing(models.Model):
level = models.ForeignKey(Level, on_delete=models.PROTECT)
price = models.PositiveSmallIntegerField(default=0)
class Enrollment(models.Model):
student = models.ForeignKey(Student, on_delete=models.PROTECT)
level = models.ForeignKey(Level, on_delete=models.CASCADE)
date_enrolled = models.DateField()
price = models.PositiveSmallIntegerField(default=0)
I want the Enrollment.price field to be populated dynamically depending on Enrollment.level field value. In javascript, it amounts to setting an event listener to Enrollement.level, but I can't find the equivalent in django.
hi you can modify your save method to fill automatically field price from Level model
Enrollment.level
class Enrollment(models.Model):
student = models.ForeignKey(Student, on_delete=models.PROTECT)
level = models.ForeignKey(Level, on_delete=models.CASCADE)
date_enrolled = models.DateField()
price = models.PositiveSmallIntegerField()
def save(self,*args,**kwargs):
self.price = Pricing.objects.get(level=self.level).price
super().save(*args,*kwargs)
but I recommend to rewrite your model like above example because its simple and you can access to price of every level directly
like Enrollment.level.price
class Level(models.Model):
level = models.CharField(max_length=50,unique=True)
price = models.PositiveSmallIntegerField(default=0)
class Enrollment(models.Model):
student = models.ForeignKey(Student, on_delete=models.PROTECT)
level = models.ForeignKey(Level, on_delete=models.CASCADE)
date_enrolled = models.DateField()
I hope it helped you

how can each user get increment and unique id on same table in django

Each time i want to add an invoice, i want to have a unique invoice_id which is an increment number (+1), but the problem is that i have a multiple users app, so i get the error that this invoice_id already exist. how can i customize the ids so each user can have its ids following the latest of same user.
class Company(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=64)
class Invoice(models.Model):
company = models.ForeignKey('Company', on_delete=models.CASCADE)
invoice_id = models.CharField(max_length=20, unique=True)
name = models.CharField(max_length=256)
add an last_invoice field in your company record. Then let it do the work for you by adding a function that generates new invoice:
class Company(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=64)
last_invoice = models.CharField(max_length=20)
def get_invoice(self):
l_newNum = self.last_invoice + '1' #your number here
self.last_invoice = l_newNum
self.save()
return l_newNum
class Invoice(models.Model):
company = models.ForeignKey('Company', on_delete=models.CASCADE)
#you no longer need unique as it will create a mess between companies
invoice_id = models.CharField(max_length=20)
name = models.CharField(max_length=256)
def save(self):
self.invoice_id = self.company.get_invoice()
super(Invoice,self).save()
You need to fill in the details here and there, but this should work for you. IDeally I would suggest that the get_invoice is actually used to automatically create Invoice entry for the company, but this would depend on the concrete case you are building.

Django Sum in Annotate

Good afternoon,
I am really struggling with getting a sum using Annotate in DJango.
I am using User object and the following models:
class Depts(models.Model):
dept_name = models.CharField(max_length=55)
dept_description = models.CharField(max_length=255)
isBranch = models.BooleanField(default=False)
def __str__(self):
return "{}".format(self.dept_name)
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='profile')
title = models.CharField(max_length=75)
dept = models.ForeignKey(Depts, on_delete=models.CASCADE, related_name="dept", null=True)
class ActivityLog(models.Model):
activity_datetime = models.DateTimeField(default=timezone.now)
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, related_name='activity_user')
activity_category = models.ForeignKey(ActivityCategory, on_delete=models.CASCADE, null=True, related_name='activity_cat')
activity_description = models.CharField(max_length=100, default="Misc Activity")
class ActivityCategory(models.Model):
activity_name = models.CharField(max_length=40)
activity_description = models.CharField(max_length=150)
pts = models.IntegerField()
def __str__(self):
return '%s' % (self.activity_name)
What I need to do is get a group of departments with aggregating the sum of the pts earned by all the users activitylogs.
So a user is part of department, they do activities, each activity is of a type activity_category and has associated points. How can I query using the ORM to get a sum of points for everyone in each department?
Thank you, I cannot seem to wrap my mind around it.
You annotate the departments with the sum:
from django.db.models import Sum
Depts.objects.annotate(
total_pts=Sum('dept__user__activity_user__activity_category__pts')
)
Note: The related_name=… parameter [Django-doc]
is the name of the relation in reverse, so from the Depts model to the UserProfile
model in this case. Therefore it (often) makes not much sense to name it the
same as the forward relation. You thus might want to consider renaming the dept relation to userprofiles.
After setting the related_name='userprofiles', the query is:
from django.db.models import Sum
Depts.objects.annotate(
total_pts=Sum('userprofiles__user__activity_user__activity_category__pts')
)

Table as field in model

I have such models:
class Department(models.Model):
name = models.CharField(max_length=30)
schedule = models.ForeignKey('Schedule', on_delete=models.CASCADE)
class Schedule(models.Model):
post_name = models.CharField(max_length=30)
shift_start = models.TimeField(auto_now=False, auto_now_add=False)
shift_end = models.TimeField(auto_now=False, auto_now_add=False)
Each department have a schedule - some [post_name, shift_start, shift_end] lines for each post. If use ForeignKey there will be only one line instead of a list. Is it possible to create some Schedule tables and link each with certain Department?
Foreign key defines a 1 to N relationship between your models. If I understood right you would like 1 department to have N schedules. To achieve this each schedule should have a foreign key defining which department it belongs to.
So you should use ForeignKey for that, but put it in your Schedule model.
Here is how it should look:
class Department(models.Model):
name = models.CharField(max_length=30)
class Schedule(models.Model):
post_name = models.CharField(max_length=30)
shift_start = models.TimeField(auto_now=False, auto_now_add=False)
shift_end = models.TimeField(auto_now=False, auto_now_add=False)
department = models.ForeignKey(Department, on_delete=models.CASCADE, related_name='schedules')
Then after you've created a department and a couple of schedules for that department you can access them like so:
(lets assume the created department primary key is 1)
Department.objects.get(pk=1).schedules.all()

Django filter many to many

If I have products that only can be sold is some regions. Also a customer can belong to several regions.
Example:
class Customer(models.Model):
firstname = models.CharField(max_length=100, default="")
class Product(models.Model):
productname = models.CharField(max_length=100, default="")
class Region(models.Model):
regionname = models.CharField(max_length=100, default="")
class CustomerRegionLink(models.Model):
customer = models.ForeignKey(Customer)
region = models.ForeignKey(Region)
class ProductRegionLink(models.Model):
product = models.ForeignKey(Product)
region = models.ForeignKey(Region)
If I now have a Customer object. How can I filter out which products can be ordered?
I have tried versions of:
thecustomer = Customer.objects.get(id=1)
prods = ProductRegionLink.object.filter(region__in=thecustomer.customerregionlink.all())
This errors like:
ValueError: Cannot use QuerySet for "CustomerRegionLink": Use a QuerySet for "Region".
Try
thecustomer = Customer.objects.get(id=1)
prods = ProductRegionLink.object.filter(region__in=[cr_link.region for cr_link in thecustomer.customerregionlink.all()])
As in your current query you are trying to find region in customerregionlink queryset not in region queryset or list.