Join trong Django

09:46 05/03/2021khienhd3 trả lời35 lượt xem

Mình gặp vấn đề về join 2 bảng trong django hoặc các câu lệnh truy vấn phức tạp. Nhưng trường hợp truy vấn phức tạp mình phải dùng SQL bình thường để dùng à bạn ơi.

Trên thực tế các dự án lớn nhiều nghiệp vụ phức tạp thì sẽ dùng cái gì để truy vấn DB vậy bạn. Hình như ORM của django không đáp ứng được hết các câu lệnh

Ví dụ

class Category(models.Model):
    category_name = models.CharField(max_length=30, blank=True)
    category_code = models.CharField(max_length=4, blank=True)
    category_desc = models.TextField(blank=True)
    date_time = models.DateField(auto_now_add=True)

class Country(models.Model):
    country_name = models.CharField(max_length=30, blank=True)
    country_code = models.CharField(max_length=4, blank=True)
    date_time = models.DateField(auto_now_add=True)


class BrandName(models.Model):
    brand_name = models.CharField(max_length=30, blank=True)
    category_id = models.ForeignKey(Category, on_delete=models.CASCADE)
    country_id = models.ForeignKey(Country, on_delete=models.CASCADE)
    broand_desc = models.TextField(blank=True)
    date_time = models.DateField(auto_now_add=True)

Mình muốn chạy câu lệnh

select broand_name , category_name, country_name from products_brandname, products_category, products_country
where products_brandname.category_id_id  = products_category.id and products_brandname.country_id_id = products_country.id 

Thì thực hiện như nào. Mong bạn trả lời

Đã chỉnh sửa lúc 13:00 05/03/2021
Gửi Trả Lời

3 trả lời cho câu hỏi

  1. Với trường hợp của bạn đâu cần join 2 bảng làm gì, hãy viết đơn giản truy vấn để maintain dễ hơn sau này:

    cat = Category.objects.get(id=1)
    
    country = Country.object.get(id=2)
    
    bn = BrandName.objecs.filter(category_id=cat, country_id=country).first()
    x = bn.country_id. country_name
    y = bn.category_id.category_name
    

    Trường hợp filter tắt dùng JOIN nó sẽ như vầy:

    print(BrandName.objects.filter(category_id__country_name='Vietnam').only('brand_name').query)
    

    Các truy vấn phức tạp với Django thì xem thêm và thực hành ở đây nhé: https://docs.djangoproject.com/en/3.1/topics/db/queries/

    Truy vấn raw SQL cũng không phải lựa chọn tồi nếu bạn nắm rõ điều mình muốn làm: https://docs.djangoproject.com/en/3.1/topics/db/sql/

    Chúc thành công!

  2. Mình đang muốn list all raw ở table brand_name và thay các id của country và category bằng name của nó.

    Các câu lện của bạn mình đã tìm cách dùng mà không được

    Mình đã sử dụng raw sql nhưng không biết cách đẩy nó qua html như nào. Mình vẫn đang học nên lẫn lộn giữa các khái niệm thấy dùng nó thật khó. Các ví dụ và các bài học mọi người đưa ra thật dễ. Nhưng để sử dụng cho 1 bài toán thực tế mình muốn dựng thì thấy khó thật

    Đã chỉnh sửa lúc 15:10 06/03/2021
  3. Mình đã làm được nhưng cảm giác cách làm cứ ngu ngu kiểu gì ấy

    def get(self, request, *args, **kwargs):
            user_id = request.user
            init_context = load_init(user_id)
            context_data = []
            for a in BrandName.objects.raw('select * from products_brandname, products_category, products_country where products_brandname.category_id_id  = products_category.id and products_brandname.country_id_id = products_country.id '):
                context = [{
                    'id': a.id,
                    'brand_name': a.brand_name,
                    'category_name': a.category_name,
                    'country_name': a.country_name,
                    'broand_desc': a.broand_desc,
                    'broand_desc': a.broand_desc,
                }]
                context_data.extend(context)
            context_data = {
                'context_data': context_data
            }
            print(context_data)  
            init_context.update(context_data) 
            print(init_context)
            return render(request, self.template_name,init_context)
    

    table bên html là

    <tbody>
                                {%  for obj in context_data %}
                                <tr>
                                    <td>{{ obj.brand_name }}</td>
                                    <td>{{ obj.country_name }}</td>
                                    <td>{{ obj.category_name }}</td>
                                    <td>{{ obj.broand_desc }}</td>
                                    <td><a href="#"><i class="fa fa-pencil"></i> Edit </a></td>
                                </tr>
                                {% endfor %}
                            </tbody>
    

    Mong bạn góp ý về cách làm.

    Thanks

    Đã chỉnh sửa lúc 16:19 06/03/2021