Django: Confused about backwards relations in views - django

I have object CarMaker:
class CarMaker(models.Model):
name = models.CharField(max_length=100)
And object CarModel stored in variable car_inst:
class CarModel(models.Model):
maker = models.ForeignKey(CarMaker, on_delete=models.CASCADE)
name = models.CharField(max_length=50, null=False, blank=False)
serial_number = models.CharField(max_length=50)
car_inst = CarModel.objects.get(id=foo)
I need to get the CarMaker that "owns" it.
I tried with:
maker = CarMaker.objects.get(id__in=car_inst.id)
This doesn't work. I've seen examples online of using backwards relations along the lines of:
maker = carmaker.carmodel_set.all()
But that didn't work either. What am I doing wrong here?

To get maker of car_inst you can just use car_inst.maker.
Reverse relations using in case you need to get list of cars related with specific maker maker.carmodel_set.all() this will give you all car models of the selected maker.

Let's take it step by step:
Get the CarModel object for which you want the CarMaker for :
car_model = CarModel.objects.get(id=foo)
Now, let us get the CarMaker associated with this object:
car_maker = car_model.maker

Related

How to call a a field of one model A into another model B so that b can work as a view

I have created a model called Department, Course. Models are as follow
This is the model for departments and course
class Departments(models.Model):
Department_Id = models.IntegerField(primary_key=True)
Department_Name = models.CharField(max_length=200)
Department_Code = models.CharField(max_length=200)
class Course(models.Model):
Course_Id = models.IntegerField(primary_key=True)
Department_Id = models.ForeignKey(Departments, on_delete=models.CASCADE)
Course_Name = models.CharField(max_length=200)
Course_Code = models.CharField(max_length=200)
I want to create a model called view which can be later on called for search. I want a view model in a such a way that it consit of the data in concat form i.e. name= Department_name+ Course_Name
class View (models.model):
view_id= models.IntegerField(primary_key=True)
Name= Department_name(I want this from Departments table)
+ Course_Name(I want this from Course table)
I try using one to one relation . I would really appricate the help
It's not clear why you'd want to do that. It's never a good idea to duplicate data from one model into another one, as it can lead to inconsistencies.
You can add a ForeignKey in View to your Course model and then when you do f"{view.course.name} {view.course.department.name}" you already have your string:
class View(models.Model):
course = models.ForeignKey(Course, on_delete=models.CASCADE)
def name(self):
return f"{self.course.name} {self.course.department.name}"
Notes:
Don't call your foreign key Department_id because it's not referring to the id but to the object itself in the Django ORM: department = models.ForeignKey(Department, on_delete=models.CASCADE). As you can see, this makes reading the code much simpler: self.course.Department_id is a Department object not an integer, so self.course.department makes more sense.
Don't prefix your field names with the class, it just makes the code so much less readable: Do you prefer department.name or department.Department_name?
The View model is still a mystery to me, as you can search without it. You can search for example for courses with a matching department name like this:
Course.objects.filter(department__name__icontains="maths")
which will return all courses with "maths" in their department name.
Remove all the ids from your models, they are created automatically by Django anyway (and called id). Again, department.id is much easier to read than department.Department_id. Also in your code, you have to generate the ids yourself since you don't set them to auto-populate.

Getting a queryset using a foreign key field in the "other side" of a foreign key relation

Forgive me if the question does not make sense, trying to teach myself django. I've been trying to search how to do this but i'm not sure if i'm using the right words in my search.
I have the following models.
class Category(models.Model):
code = models.CharField(max_length=10, unique=True)
description = models.CharField(max_length=50)
class UserGroupHeader(models.Model):
code = models.CharField(max_length=10, unique=True)
description = models.CharField(max_length=50)
class UserGroupDetail(models.Model):
usergroupheader = models.ForeignKey(UserGroupHeader, on_delete=models.CASCADE)
category = models.ForeignKey(Category, on_delete=models.PROTECT)
How do i get a query set from the Category model using the UserGroupHeader? so far what i've got is something like this UserGroupHeader.objects.get(pk=9).usergroupdetail_set.all(), now from the result of this how do i get the Category model?
I'm not sure if I understood exactly what you are trying to do, but in general, while querying, you can follow relations using double underscores. Below are a couple of possible queries:
my_group_header = UserGroupHeader.objects.get(...)
Category.objects.filter(usergroupdetail__usergroupheader=my_group_header) # Gets Category objects related to my_group_header through UserGroupDetail model
Category.objects.filter(usergroupdetail__usergroupheader__code='abc') # Gets Category objects related to UserGroupHeader object with code 'abc' through UserGroupDetail model
UserGroupHeader.objects.filter(usergroupdetail__category__code='abc') # Gets UserGroupHeader objects related to Category object with code 'abc' through UserGroupDetail model
Your query UserGroupHeader.objects.get(pk=9).usergroupdetail_set.all() would return a QuerySet of UserGroupDetail objects. In order to get the category of each UserGroupDetail, you can:
for user_group_detail in UserGroupHeader.objects.get(pk=9).usergroupdetail_set.all():
category = user_group_detail.category
print(category. description)
Or something similar according to your needs

Is there any possible solution for getting more than one value inside function in django?

I am creating a blog application using Django and I am also very much new to django.
This is the models I created
class categories(models.Model):
Title = models.CharField(max_length=40, default='GST')
class Blog(models.Model):
User = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE,null=True,blank=True)
Date = models.DateTimeField(default=datetime.now)
Blog_title = models.CharField(max_length=255)
likes = models.ManyToManyField(settings.AUTH_USER_MODEL,related_name='likes',blank=True)
Description = RichTextUploadingField(blank=True, null=True,config_name='special')
Blog_image = models.ImageField(upload_to='blog_image', null=True, blank=True)
Category = models.ForeignKey(categories,on_delete=models.CASCADE,related_name='blogs')
I was wondering How to count the total no of blog present under a particular category?
I want to track a specific count rate for all Categories...
Done something like this in my model
def categories_count(self):
for a in categories.objects.all():
categories_count = Blog.objects.filter(Category__Title=a.Title).count()
return categories_count
But it is returning only one value...Can anyone suggest me with some suitable codes to resolve this...
Thank you
You can get a list of tuples of category title and blog count with the following query:
categories.objects.annotate(blog_count=Count('Categories')).values_list('Title', 'blog_count')

How do I make this model query work?

I'm trying to find a solution that will return the objects with a specific id.
I have these models:
class ModelB(models.Model):
customid = models.CharField(max_length=32)
<-- data -->
class ModelA(models.Model):
b = models.ForeignKey(ModelB, blank=True, null=True, related_name="Bs")
and I have this code in my views:
a = ModelA.objects.filter(ModelB__customid = Bobject_id)
I want to be able to find all of the A objects with a given B object.
Any ideas?
a_objects = ModelA.objects.filter(b__customid=Bobject_id)
Check out the documentation for creating queries that span relationships
Assuming you have an instance of ModelB, the easiest way is to follow the reverse relationship from there:
a_objects = b_object.Bs.all()
This uses the explicit related_name you have set: without that, it would have been b_object.modela_set.all(). Note that your related_name should really be "As", not "Bs", since it refers to the A objects that are related to that B.

django acces model field by string

I was wondering if it is possible to acces a field in a djangomodel from a string. Letme give you an example:
class:
class Resource(models.Model):
town = models.ForeignKey(Town, unique=True)
coin = models.IntegerField()
wood = models.IntegerField()
iron = models.IntegerField()
grain = models.IntegerField()
stone = models.IntegerField()
Now somewhere in my other code, i would like to acces a field like this
example="coin"
resources = Resource.objects.get(town="some town"):
resources.example
I know the resources.example doesnt work, i was wondering if there was some way to achieve that?
With kind regards,
Hans de Jong
You can access an attribute of any object in python by name using the getattr built-in function
example="coin"
resources = Resource.objects.get(town="some town"):
getattr(resources, example)