Search code examples
pythondjangodjango-modelsdjango-viewsdjango-datatable

How to get table 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 = Vehicles.objects.filter(id=vehicles.vehicle_id)  # Not Working

How do I get data from tables whose multiple id's obtained by another table?

Models

class Company(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)
    slug = models.SlugField(blank=True, null=True, unique=True)
    description = models.TextField()

class Vehicles(models.Model):
    id = models.AutoField(primary_key=True)
    vehicle_number = models.IntegerField()
    name = models.CharField(max_length=255)
    slug = models.SlugField(blank=True, null=True, unique=True)


class CompanyContainVehicles(models.Model):
    id = models.AutoField(primary_key=True)
    company_id = models.ForeignKey(Company, on_delete=models.CASCADE)
    vehicle_id = models.ForeignKey(Vehicles, on_delete=models.CASCADE)
    created_at = models.DateTimeField(auto_now_add=True, blank=True)

Above are my table details and I need to get all vehicles from table Vehicles which is obtained from CompanyContainVehicle table (that define which company seel out which vehicle) based on company_id that obtain from table Company which contains details of companies.


Solution

  • You can filter with:

    Vehicles.objects.filter(companycontainvehicles__company_id=company_id)

    Here your companycontainvehicles basically acts as a ManyToManyField. You can span a many-to-many relation between Vehicle and Company with:

    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)

    Then you can filter with:

    Vehicle.objects.filter(companies=company_id)

    Note: normally a Django model is given a singular name, so Vehicle instead of Vehicles.


    Note: Normally one does not add a suffix _id to a ForeignKey field, since Django will automatically add a "twin" field with an _id suffix. Therefore it should be company, instead of company_id.