djangodjango-ormdjango-select-related

How to remove duplicates in a django request


Remove duplicates in a Django query Image SQL duplicate. I used select_related and reduced the number of requests from 90 to 18, but if the database grows, then this will not save me. How can the query be improved?

views.py

def index(request):  
    snj = ScheduleNotJob.objects.select_related()
    form = SNJ()
    return render(request,"index.html",{'snj': snj, 'form':form})  
models.py



class Office(models.Model):  
    title = models.CharField(max_length=150, db_index=True)  

    def __str__(self):
        return self.title
            

class Post(models.Model):
    office = models.ForeignKey(Office, on_delete=models.CASCADE)  
    title = models.CharField(max_length=150, db_index=True)

    def __str__(self):
        return self.title


class Human(models.Model):  
    office = models.ForeignKey(Office, on_delete=models.CASCADE)  
    post = ChainedForeignKey(
        Post, 
        chained_field="office",
        chained_model_field="office", 
        show_all=False, 
    )  
    initials = models.CharField(max_length=150, db_index=True)  


    def __str__(self):
        return self.initials


class Reason(models.Model):  
    title = models.CharField(max_length=150) 

    def __str__(self):
        return self.title


class Shift(models.Model):  
    title = models.CharField(max_length=150) 

    def __str__(self):
        return self.title
    

class ScheduleNotJob(models.Model):
    shift = models.ForeignKey(Shift, on_delete=models.CASCADE) 
    office = models.ForeignKey(Office, on_delete=models.CASCADE) 
    post = GroupedForeignKey(Post, "office") 
    human = GroupedForeignKey(Human, "post") 
    reason = models.ForeignKey(Reason, on_delete=models.CASCADE)
    comment = models.CharField(max_length=300, blank=True, null=True)
    length_time = models.IntegerField(blank=True, null=True)
    date_start = models.DateField(blank=True, null=True) 
    date_end = models.DateField(blank=True, null=True) 
index.html


{% for elem in snj %}  
    <tr class="mySelect">  
    <td>{{ elem.id }}</td>  
    <td>{{ elem.shift }}</td> 
    <td>{{ elem.office }}</td> 
    <td>{{ elem.post }}</td> 
    <td>{{ elem.human }}</td>  
    <td>{{ elem.reason }}</td>  
    <td>{{ elem.comment }}</td> 
{% endfor %}

I used select_related and reduced the number of requests from 90 to 18, but if the database grows, then this will not save me. How can the query be improved?


Solution

  • You can use the Only() method and pass the required fields, which are loaded immediately when the queryset is evaluated.

    def index(request):  
        snj = ScheduleNotJob.objects.select_related(
            'shift', 'office', 'post', 'human'
        ).only(
            'id', 'reason', 'comment', 'shift_id', 'shift__title', 'office_id', 'office__title', 'post_id', 'post__title', 'human_id', 'human__initials'
        )
        form = SNJ()
        return render(request,"index.html",{'snj': snj, 'form':form})