Django SELECT (1) AS [a] FROM [my_table] WHERE ([my_table]. [Id] =? AND NOT ([my_table]. [Id] =?)) (1, 1) - PullRequest
3 голосов
/ 11 февраля 2010

Почему Джанго выполняет такие выражения, как это:

SELECT (1) AS [a] FROM [my_table] 
WHERE ([my_table].[id] = ?  
AND NOT ([my_table].[id] = ? )) (1, 1)

Это происходит при вызове is_valid () для набора форм, созданного следующим образом:

MyFormSet = modelformset_factory(Table, fields=['my_field'], extra=0)
my_form_set = MyFormSet(request.POST,
                        queryset=Table.objects.all())

где Table и MyForm так же просты, как:

class Table(models.Model):
    my_field = models.CharField(max_length=10)

class MyForm(forms.ModelForm):
    class Meta:
        model = Table

Подсказка: я посмотрел на стек вызовов и код, ответственный за него (в django / forms / models.py), ниже:

def _perform_unique_checks(self, unique_checks):
    import pdb; pdb.set_trace()
    bad_fields = set()
    form_errors = []

    for unique_check in unique_checks:
        # Try to look up an existing object with the same values as this
        # object's values for all the unique field.

        lookup_kwargs = {}
        for field_name in unique_check:
            lookup_value = self.cleaned_data[field_name]
            # ModelChoiceField will return an object instance rather than
            # a raw primary key value, so convert it to a pk value before
            # using it in a lookup.
            if isinstance(self.fields[field_name], ModelChoiceField):
                lookup_value =  lookup_value.pk
            lookup_kwargs[str(field_name)] = lookup_value

        qs = self.instance.__class__._default_manager.filter(**lookup_kwargs)

        # Exclude the current object from the query if we are editing an
        # instance (as opposed to creating a new one)
        if self.instance.pk is not None:
            qs = qs.exclude(pk=self.instance.pk)

В основном, ПК включен как для проверки уникальности, так и исключен. Похоже, Джанго может быть умнее и избежать такой неэффективности.

Ответы [ 2 ]

1 голос
/ 15 февраля 2010

Я не рассматривал это подробно, но я думаю, что вы правы, что Django мог бы сократить этот запрос Пожалуйста, подайте заявку на http://code.djangoproject.com/.

0 голосов
/ 15 февраля 2010

Похоже, это уже исправлено в транке (добавлена ​​новая функциональность, которая также решает эту конкретную проблему)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...