Django - Relationships in Models - python

In Django there are field types called ForeignKey and OneToMany/OneToOne, I was wondering would I use ForeignKey or the relationship type as the field type in this scenario? User to Profile has been identified as OneToOne but I'm unsure about the others.
class Profile(models.Model):
user = models.OneToOneField(User, on_delete = models.CASCADE)
fullname = models.CharField(max_length=100)
dob = models.DateField()
address = models.TextField()
city = models.CharField(max_length=100)
profilephoto = models.ImageField(default='default_profile.jpg', upload_to='reviewApp/static/profile_images')
class Product(models.Model):
name = models.CharField(max_length=100)
brand = models.CharField(max_length=100)
cost = models.DecimalField(max_digits=8, decimal_places=2, default=0.00)
category = models.CharField(max_length=100)
releasedate = models.DateField()
description = models.TextField()
productphoto = models.ImageField(default='default_product.jpg', upload_to='reviewApp/static/product_images')
class Review(models.Model):
product = models.ForeignKey(Product)
profile = models.ForeignKey(Profile)
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = model.PositiveSmallIntegerField(default=1, validators = [MinValueValidator(1), MaxValueValidator(5)])
reviewtext = models.TextField()
postdate = models.DateTimeField(auto_now_add=True)
lastmodified = models.DateTimeField(auto_now=True)

So from what I see here, it seems to be good if the following is what you want:
User can have only one profile and one Profile is related to only one user.
a Profile can make multiple Review but a Review belongs to only one profile.
A Product can have multiple Review but a Review is specific to one Product.
Be carefull to define the on_delete argument for your foreign keys depending of what you want to keep in your database after a delete.
More info from the doc : https://docs.djangoproject.com/fr/2.2/ref/models/fields/#arguments

Related

How to get table data (including child table and sub child data) based on id which obtains from another table data? Django

views
company = Company.objects.get(id = company_id) # getting input from django urls (<int:company_id>)
vehicles = CompanyContainVehicles.objects.filter(company_id=company.id) # Give all rows having same id (company.id)
all_vehicles = Vehicle.objects.filter(companies=company) # Gives all row with id provide by company
all_vehicles_parts = VehiclePart.objects.filter(__________) # Not Working
models
class Company(models.Model):
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True, unique=True)
description = models.TextField()
class Vehicle(models.Model):
vehicle_number = models.IntegerField()
name = models.CharField(max_length=255)
slug = models.SlugField(blank=True, null=True, unique=True)
companies = models.ManyToManyField(
Company,
through='CompanyVehicle',
related_name='companies'
)
class CompanyVehicle(models.Model):
company = models.ForeignKey(Company, on_delete=models.CASCADE)
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
class VehiclePart(models.Model):
id = models.AutoField(primary_key=True)
vehicle = models.ForeignKey(Vehicle, on_delete=models.CASCADE)
type = models.ForeignKey(PartType, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True, blank=True)
How do I get VehiclePart's with their Vehicle? (I think I will give all the data in a variable and we should divide it and add it with their Vehicle). Also, what can we do to access data if VehiclePart contains a child class named VehiclePartDetail?
I think I will give all the data in a variable and we should divide it and add with their Vehicle.
You don't have to. Django can read ForeignKey relations in reverse. You can query with:
qs = Vehicle.objects.prefetch_related('vehiclepart_set')
then you can enumerate over the queryset, and for each Vehicle object, access this with .vehiclepart_set.all(). For example:
for item in qs:
print(vehicle_name)
for part in item.vehiclepart_set.all():
print(part.id)

message_set of Django model

i'm new with Django and as I read the code, I don't understand the message_set attribute of Django model(called Room):
def room(request, pk):
room = Room.objects.get(id=pk)
**room_messages = room.message_set.all()**
participants = room.participants.all()
portion of Models:
class Room(models.Model):
host = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
topic = models.ForeignKey(Topic, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=200)
description = models.TextField(null=True, blank=True)
participants = models.ManyToManyField(
User, related_name='participants', blank=True)
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Message(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
room = models.ForeignKey(Room, on_delete=models.CASCADE)
body = models.TextField()
updated = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
If you define a ForeignKey from Message to Room, Django will add a relation in reverse to the from the Room model to its related Messages. By default this relation is named modelname_set with modelname the name of the origin of the model. You can specify another name by overriding the related_name=… parameter [Django-doc].
If you thus access the relation in reverse, you get all Message objects with room as there room, an equivalent query to room.message_set.all() is thus Message.objects.filter(room=room).

Django - limit choices to foreign key

I have the following model in Django
class Transfer(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, limit_choices_to={'is_accepted':True})
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)
I would like to filter the users based on is_accepted field. The problem is, that this field is declared in a model called Employee, which is in onetoone relationship with user.
Is there any possibility to reach Employee fields and filter them in this manner?
You can normally define a filter like:
class Transfer(models.Model):
user = models.ForeignKey(
User,
on_delete=models.PROTECT,
limit_choices_to={'employee__is_accepted': True}
)
amount = models.IntegerField(default=0)
transfer_date = models.DateTimeField(default=timezone.now)
company = models.ForeignKey(Company, on_delete=models.PROTECT)

how to add options in select field dynamically in django?

models.py
class Add_category(models.Model):
Category = models.CharField(max_length=100)
Image = models.ImageField()
MetaKeyword = models.CharField(max_length=100)
MetaDesc = models.CharField(max_length=100)
def __str__(self):
return self.Category
In this, I have tried to add city field and choices must come in this
field by the help of Add_category model but it fails.
class Make_Invoice(models.Model):
Order_no = models.IntegerField()
Invoice_no = models.IntegerField()
Product_name = models.CharField(max_length=100)
Product_Id = models.IntegerField()
Quantity = models.IntegerField()
City = models.CharField(max_length=100, choices = Add_category.Category, default='Select')
Why even use City as a as a CharField? As far as I see it should be a ForeignKey - ManyToOne or even ManyToMany relation.
Check it in the documentation:
https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_one/
https://docs.djangoproject.com/en/2.2/topics/db/examples/many_to_many/
Use a ForeignKey
City = models.ForeignKey('Add_category', on_delete=models.PROTECT)

Django - how to query all users associated with a "listing" object

My models look like this:
CustomUser has a many to many relationship with a "Listing" object
Each Listing object has an "author" field
author = models.ForeignKey(CustomUser)
Essentially, a listing has both an author (CustomUser) and custom users who need confirmation.
I'm trying to get all the custom users who need confirmation for all the listings posted by the author.
I'm not sure what the correct way to query is.
Listing.objects.filter(author=author).needsConfirmation_set.all()
The models
class CustomUser(models.Model):
user = models.OneToOneField(User)
location = models.CharField(max_length=50)
rating = models.FloatField(null=True)
level = models.CharField(max_length=50)
followers = models.ManyToManyField("self", related_name="followers")
following = models.ManyToManyField("self", related_name="following")
interested = models.ManyToManyField('Listing', related_name = 'interested', default=None)
needsConfirmation = models.ManyToManyField('Listing', related_name = 'needsConfirmation', default=None)
confirmed = models.ManyToManyField('Listing', related_name = 'confirmed', default=None)
class Listing(models.Model):
subject = models.CharField(max_length=42)
location = models.CharField(max_length=50, default="N/A")
description = models.CharField(max_length=500)
author = models.ForeignKey(CustomUser)
date = models.DateTimeField(default=timezone.now)
I think it's as simple as:
CustomUser.objects.filter(needsconfirmation__author=author)

Categories

Resources