How to store multiple values inside a foreign key field? - python-3.x

I need to add multiple categories to a brand field. Here is the code
class Brand_Category(models.Model):
"""
this model is use to store the data of products category
"""
name = models.CharField(max_length=50, unique=True, verbose_name="Brand Category Name")
slug = models.SlugField(max_length=140, unique=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
class Brand(models.Model):
"""
This model is use to store the data of products sub category
"""
user = models.ForeignKey(User, related_name='brand_user', on_delete=models.CASCADE,null=True,blank=True, default=None)
name = models.CharField(max_length=50, unique=True, verbose_name="Brand Name")
brand_img = models.FileField(verbose_name='Upload Image')
category = models.ForeignKey(Brand_Category, related_name='brand_category', on_delete=models.PROTECT, null=True)
slug = models.SlugField(max_length=140, unique=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)
I have a brand form where I am adding multiple categories.
This categories are stored in the brand_category model, and i would like to save the id of multiple categories into one brand field. how can i add that?
i have found about onetomany field in django but it seems to have deprecated, and the other soultions are not similar to my problem. However, a cateogry is not strictly related to any brand.
Here is the insertion code
brand_name = request.POST["brand_name"]
image = request.FILES['image']
brand_category = request.POST.getlist("brand_category")
brand = models.Brand.objects.create(
user = request.user,
name = brand_name,
brand_img = image,
category_id = brand_category,
).save()

Try using many to many relationships as the brand_category_field. With this relationship you can have one brand related to multiple categories and yet a category can not be restricted to a single brand.

Foreign Key is One to Many Relation. In your case, one category can have many Many Brands so if the brand has to be in another category also means in that case you have to change the relationship from Foreign key relation to Many-to-Many Relation.
Check the below link for reference
https://docs.djangoproject.com/en/4.0/topics/db/examples/many_to_many/
class Brand(models.Model):
"""
This model is use to store the data of products sub category
"""
user = models.ForeignKey(User, related_name='brand_user', on_delete=models.CASCADE,null=True,blank=True, default=None)
name = models.CharField(max_length=50, unique=True, verbose_name="Brand Name")
brand_img = models.FileField(verbose_name='Upload Image')
category = models.ManyToManyField(Brand_Category,related_name='brand_category')
slug = models.SlugField(max_length=140, unique=True, blank=True)
created_at = models.DateTimeField(auto_now_add=True, null=True, blank=True)

Related

Left Join in Django

I have the following models:
class Patient(models.Model):
patient_first_name = models.CharField(max_length=50)
patient_last_name = models.CharField(max_length=50)
patient_name = models.CharField(max_length=100)
patient_email = models.EmailField(max_length=100)
gender = models.CharField(max_length=50)
class PatientMedicalRecord(models.Model):
patient = models.ForeignKey(Patient)
mrn = models.CharField(max_length=50, unique=True)
patient_height = models.IntegerField(blank=True, null=True)
patient_weight = models.IntegerField(blank=True, null=True)
age_risk = models.BooleanField(default=False)
I want to query on patient table for getting all the patient. also i need MRN column value from PatientMedicalRecord table which contain record for particular patient if exists.
How can i do this with djnago ORM?
Following are sql query gives me perfect result.
SELECT a.id,--remaining field, b.mrn FROM patient as a LEFT JOIN patient_medical_record as b ON a.id=b.patient_id;
How can i do this with django annotate ?
You can fetch related objects using the object_set. In your example, here is how you would do it:
patient = Patient.objects.get(pk=1) # You can use any attribute to get the Patient object
patient_medical_records = patient.patientmedicalrecord_set.all()
patient_mrns = []
for record in patient_medical_records:
patient_mrns.append(record.mrn)
You can also defined a related_name property in your model for the relationship to query relationships with. For example:
class PatientMedicalRecord(models.Model):
patient = models.ForeignKey(Patient, on_delete=models.CASCADE, related_name='patient_records')
Then you would query it like this:
patient = Patient.objects.get(pk=1)
patient_medical_records = patient.patient_records.all()

Django Subquery many values

class Category(models.Model):
name = models.CharField(max_length=100)
date = models.DateTimeField(auto_now=True)
class Hero(models.Model):
name = models.CharField(max_length=100)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
I want Categoty model name, data, id
In cookbook , I wrote the code as above.
hero_qs = Hero.objects.filter(
category=OuterRef("pk")
).order_by("-benevolence_factor")
Category.objects.all().annotate(
most_benevolent_hero=Subquery(
hero_qs.values('name')[:1]
)
)
It seems that only one value can be entered in hero_qs.values('name')
Is it possible to get name, data, id with one annotate?
You can try Concatenating the fields if you really want to use a single annotation
from django.db.models import Subquery, OuterRef, CharField, Value as V
from django.db.models.functions import Concat
hero_qs = Hero.objects.filter(
category=OuterRef("pk")
).order_by("-benevolence_factor").annotate(
details=Concat('name', V(','), 'id', output_field=CharField())
)
Category.objects.all().annotate(
most_benevolent_hero=Subquery(
hero_qs.values('details')[:1]
)
)
Then you can use string interpolation to separate that data out which is a relatively inexpensive operation
name, id = category.most_benevolent_hero.split(',')

fetching not with custom primary id in django

I have created a table in which the primary id have to customize id product_id like
class Product(models.Model):
product_id = models.BigIntegerField(auto_created = True,primary_key = True, unique=True)
name = models.CharField(max_length=200)
ref = models.CharField(max_length=100)
number= models.CharField(max_length=100)
class Meta:
db_table = "products"
def __str__(self):
return self.name
after creating the record I want to get the id of the latest record but when I retrieve the data with this id getting None
product = Product.objects.create(name=name, ref=ref, number=number)
print(product.product_id)
product.product_id id getting null
Pleae give me a solution to why this is happening.
Django will set the primary key of an AutoField or BigAutoField, given that the database supports returning the assigned primary key.
You thus should rewrite the model to:
class Product(models.Model):
product_id = models.BigAutoField(primary_key=True)
# …
The reason for this is that Django does not know what the primary key (pk) of the object is going to be before the object is saved in the database.
That is because Django does not determine the value of the pk for the incoming object, your database does. In order to get the pk, you first have to save the object then retrive its pk.

DJANGO - Get values from model by join of two tables

I'm trying to get all data from a table by a model, i can get all data from the table this works ok, but i need get data from other table mapped by a foreign key to another table, this means i have a field called ID_USUARIO in Parcela Model and i want to get all data that have my actual query with the value from the other table called FULLNAME in Usuario Model.
How can i do that?
Usuario Model
class Usuario(Model):
ID_USER = models.AutoField(primary_key=True)
FULLNAME = models.CharField(max_length=500)
EMAIL = models.EmailField()
PASSWORD = models.CharField(max_length=450)
Parcela Model
class Parcela(Model):
"""docstring for Parcela."""
ID = models.AutoField(primary_key=True)
ID_USUARIO = models.ForeignKey(Usuario, on_delete=models.CASCADE)
ID_PARCELA = models.BigIntegerField()
A_DEAD_LEAVES = models.FloatField()
A_SOIL_DEPTH = models.FloatField()
A_LIGHT_FUEL = models.FloatField()
A_DUFF = models.FloatField()
A_MID_HEA_FUEL = models.FloatField()
A_SOIL_ROCK_COLOR = models.FloatField()
B_DOMINANT_VEG_TYPE = models.CharField(max_length=200)
B_FCOV = models.FloatField()
B_FOLIAGE_ALTERED = models.FloatField()
B_FREQ_LIVING = models.FloatField()
B_NEW_SPROUTS = models.FloatField()
C_DOMINANT_VEG_TYPE = models.CharField(max_length=200)
C_FCOV = models.FloatField()
C_FOLIAGE_ALTERED = models.FloatField()
C_FREQ_LIVING = models.FloatField()
C_LAI_CHANGE = models.FloatField()
D_DOMINANT_VEG_TYPE = models.CharField(max_length=200)
...
This is the query i'm doing
export = Parcela.objects.select_related('ID_USUARIO')
Result of query
ID,ID_USUARIO,ID_PARCELA,A_DEAD_LEAVES,A_SOIL_DEPTH,A_LIGHT_FUEL,A_DUFF,A_MID_HEA_FUEL,A_SOIL_ROCK_COLOR,B_DOMINANT_VEG_TYPE,B_FCOV,B_FOLIAGE_ALTERED,B_FREQ_LIVING,B_NEW_SPROUTS,C_DOMINANT_VEG_TYPE,C_FCOV,C_FOLIAGE_ALTERED,C_FREQ_LIVING,C_LAI_CHANGE,D_DOMINANT_VEG_TYPE,D_FCOV,D_GREEN_UNALTERAD,D_BLACK_BROWN,D_FREQ_LIVING,D_LAI_CHANGE,D_CHAR_HEIGHT,E_DOMINANT_VEG_TYPE,E_FCOV,E_GREEN_UNALTERAD,E_BLACK_BROWN,E_FREQ_LIVING,E_LAI_CHANGE,E_CHAR_HEIGHT,COORDINATE_X,COORDINATE_Y,DATE_CAPTURED,DATE_SAVED,PHOTO_1,PHOTO_2,PHOTO_3,PHOTO_4,PHOTO_5,SEVERITY
2,1,1,20.0,30.0,10.0,20.0,15.0,6.0,Cactus,12.0,11.0,13.0,3.0,Pasto,2.0,6.0,2.0,3.1,Arbol,1.2,14.0,8.0,4.0,0.5,2.0,Hongos,3.0,1.9,11.0,10.2,20.1,18.4,624811.32,665561.23,2019-08-27 16:56:20,2019-08-27 16:56:20,,,,,,Moderada
3,1,1,20.0,30.0,10.0,20.0,15.0,6.0,Cactus,12.0,11.0,13.0,3.0,Pasto,2.0,6.0,2.0,3.1,Arbol,1.2,14.0,8.0,4.0,0.5,2.0,Hongos,3.0,1.9,11.0,10.2,20.1,18.4,624811.32,665561.23,2019-08-27 16:56:20,2019-08-27 16:56:20,,,,,,Moderada
4,1,1,20.0,30.0,10.0,20.0,15.0,6.0,Cactus,12.0,11.0,13.0,3.0,Pasto,2.0,6.0,2.0,3.1,Arbol,1.2,14.0,8.0,4.0,0.5,2.0,Hongos,3.0,1.9,11.0,10.2,20.1,18.4,624811.32,665561.23,2019-08-27 22:46:52,2019-08-25 15:46:12,,,,,,Moderada
5,1,2,100.0,2.0,2.1,1.2,1.0,1.1,Margaritas,40.0,0.3,1.25,2.65,Pinos,2.0,6.0,2.0,3.1,Guayacan,1.2,14.0,8.0,4.0,0.5,2.0,Roble,3.0,1.9,11.0,10.2,20.1,18.4,624811.32,665561.23,2019-08-24 22:46:52,2019-08-28 15:46:12,,,,,,Alta
6,2,3,100.0,2.0,2.1,1.2,1.0,1.1,Cedro,40.0,0.3,1.25,2.65,Rosas,2.0,6.0,2.0,3.1,Savila,1.2,14.0,8.0,4.0,0.5,2.0,Eucalipto,3.0,1.9,11.0,10.2,20.1,18.4,624811.32,665561.23,2019-08-24 22:46:52,2019-08-28 15:46:12,,,,,,No Quemada
Yes, you are doing it correctly. One must use select_related to do join in django. you can verify the generated query
result = Parcela.objects.select_related('ID_USUARIO')
print(str(result.query))
# You can access ID_USARIO fields like this
print(result.first().ID_USARIO.FULLNAME)
To get rows in parcela table with a name, you can do reverse lookup. Then the query will be
result = Usuario.objects.get(FULLNAME='<name_to_filter>')
parcela_rows = result.parcela_set.all()

How to query just one or two column from a Table in flask-sqlalchemy?

I have a table say CATEGORY, and one of its column is CATEGORY_NAME.
I want to query all the category_names from the table.
In SQL I would do-
SELECT CATEGORY_NAME FROM CATEGORY;
How can I do this in flask-sqlalchemy?
My model is:
class Category(db.Model):
id = db.Column(db.Integer, primary_key=True)
category_name = db.Column(db.String(64), index=True, unique=True)
I read we can do this with with_entities, but it didn't work.
It worked this way with with_entities:
cat_names = Category.query.with_entities(Category.category_name).all()

Resources