Fortunately; I found the missing part, in documentation it say (Changing 
the queryset 
<https://docs.djangoproject.com/en/3.0/topics/forms/modelforms/#changing-the-queryset>
):

> By default, when you create a formset from a model, the formset will use a 
> queryset that includes all objects in the model (e.g., 
> Author.objects.all()). You can override this behavior by using the queryset 
> argument:

I was not changing changing the queryset before validating the formset 
which caused Django to retrieve the entire underlying model and include all 
objects in the model. I should have used the same queryset used to generate 
the formset in creating the form that will be validated. The validation 
should go like this:

qs = prs.objects.filter(Q(cid = 1243) | Q(pid = 1243))
form=prelations(data=datana, queryset = qs)


On Wednesday, July 29, 2020 at 2:25:30 AM UTC+3, Abdulrahman Alahaideb 
wrote:
>
> I have a modelformset when is_valid method is called the entire model 
> objects of the underlying form is retrieved from the database which is not 
> efficient if the database table contains hundred of thousands records, I 
> believe Django was not designed with this deficiency and there must be 
> something wrong with my code, When is_valid is called these queries are 
> sent to the database, the first query has no WHERE clause which means it 
> will retrieve the entire table!:
>
> [{'sql': 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'},{'sql': 'SET SESSION 
> TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
> **{'sql': 'SELECT `npr`.`rid`, `npr`.`PID`, `npr`.`rel`, `npr`.`CID` FROM 
> `npr` ORDER BY `npr`.`rid` ASC', 'time': '0.037'}**{'sql': 'SELECT 
> `person_details`.`ID`, `person_details`.`firstName` FROM `person_details` 
> WHERE `person_details`.`ID` = 198 LIMIT 21', 'time': '0.001'},{'sql': 'SELECT 
> `person_details`.`ID`, `person_details`.`firstName` FROM `person_details` 
> WHERE `person_details`.`ID` = 1243 LIMIT 21', 'time': '0.000'},{'sql': 
> 'SELECT `npr`.`rid`, `npr`.`PID`, `npr`.`rel`, `npr`.`CID` FROM `npr` WHERE 
> `npr`.`rid` = 1377 LIMIT 21', 'time': '0.000'},{'sql': 'SELECT (1) AS `a` 
> FROM `person_details` WHERE `person_details`.`ID` = 198 LIMIT 1', 'time': 
> '0.000'},{'sql': 'SELECT (1) AS `a` FROM `person_details` WHERE 
> `person_details`.`ID` = 1243 LIMIT 1', 'time': '0.000'},{'sql': 'SELECT (1) 
> AS `a` FROM `npr` WHERE (`npr`.`CID` = 1243 AND `npr`.`PID` = 198 AND NOT 
> (`npr`.`rid` = 1377)) LIMIT 1', 'time': '0.000'},{'sql': 'SELECT 
> `person_details`.`ID`, `person_details`.`firstName` FROM `person_details` 
> WHERE `person_details`.`ID` = 200 LIMIT 21', 'time': '0.000'},{'sql': 'SELECT 
> `person_details`.`ID`, `person_details`.`firstName` FROM `person_details` 
> WHERE `person_details`.`ID` = 1243 LIMIT 21', 'time': '0.004'},{'sql': 
> 'SELECT `npr`.`rid`, `npr`.`PID`, `npr`.`rel`, `npr`.`CID` FROM `npr` WHERE 
> `npr`.`rid` = 1378 LIMIT 21', 'time': '0.000'},{'sql': 'SELECT (1) AS `a` 
> FROM `person_details` WHERE `person_details`.`ID` = 200 LIMIT 1', 'time': 
> '0.000'},{'sql': 'SELECT (1) AS `a` FROM `person_details` WHERE 
> `person_details`.`ID` = 1243 LIMIT 1', 'time': '0.000'},{'sql': 'SELECT (1) 
> AS `a` FROM `npr` WHERE (`npr`.`CID` = 1243 AND `npr`.`PID` = 200 AND NOT 
> (`npr`.`rid` = 1378)) LIMIT 1', 'time': '0.000'}]
>
> The models
>
>    class PersonDetails(models.Model):
>         id = models.AutoField(db_column='ID', primary_key=True)
>         firstname = models.CharField(db_column='firstName', max_length=20)
>     
>         class Meta:
>             managed = True
>             db_table = 'person_details'
>     
>     
>     class Npr(models.Model):
>         rid = models.AutoField(db_column='rid', primary_key=True)
>         pid = models.ForeignKey(PersonDetails, on_delete=models.CASCADE, 
> db_column='PID', related_name='pid')
>         rel = models.CharField(max_length=1)
>         cid = models.ForeignKey(PersonDetails, on_delete=models.CASCADE, 
> db_column='CID', related_name='cid')
>     
>         class Meta:
>             managed = True
>             db_table = 'npr'
>             unique_together = (('pid', 'cid'),)
>
> and Form definition:
>
> class prelation(ModelForm):
>     class Meta:
>         model = Npr
>         fields = ['pid', 'rel', 'cid']
>         widgets = {'pid':HiddenInput(), 'rel':HiddenInput(), 
> 'cid':HiddenInput()}
>
> prelations = modelformset_factory(Npr, form = prelation, can_delete=True, 
> extra=1)
>
>
> I am using the Django shell to test because I want to make the question 
> concise and avoid the complexities of the full application and both gave 
> the same results.
>
> >>> from tstapp.forms import prelations>>> >>> >>> 
> >>> datana={'form-TOTAL_FORMS':'2',... 'form-INITIAL_FORMS':'2',... 
> >>> 'form-MIN_NUM_FORMS':'0',... 'form-MAX_NUM_FORMS':'1000',... 
> >>> 'form-0-pid':'198',... 'form-0-rel':'F',... 'form-0-cid':'1243',... 
> >>> 'form-0-rid':'1377',... 'form-0-DELETE':'None',... 'form-1-pid':'200',... 
> >>> 'form-1-rel':'M',... 'form-1-cid':'1243',... 'form-1-rid':'1378',... 
> >>> 'form-1-DELETE':'None'}>>> >>> form=prelations(data=datana)>>> 
> >>> connection.queries[]>>> form.is_valid()True>>> connection.queries[{'sql': 
> >>> 'SELECT @@SQL_AUTO_IS_NULL', 'time': '0.000'}, {'sql': 'SET SESSION 
> >>> TRANSACTION ISOLATION LEVEL READ COMMITTED', 'time': '0.000'},
>
>  {'sql': 'SELECT `npr`.`rid`, `npr`.`PID`, `npr`.`rel`, `npr`.`CID` FROM 
> `npr` ORDER BY `npr`.`rid` ASC', 'time': '0.037'}, {'sql': '
>
> How to optimize the queries sent to database when is_valid method is 
> called against a modelformset?
>
>
> I am using Django Version: 3.0.4, Python version: 3.7.3, Database: 
> 10.3.22-MariaDB-0+deb10u1-log
>

-- 
You received this message because you are subscribed to the Google Groups 
"Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-users/5116b61c-ff98-45a8-89a9-eae0ab44a1b7o%40googlegroups.com.

Reply via email to