не могу запросить от Django, где имя поля имеет двойное подчеркивание - PullRequest
2 голосов
/ 25 сентября 2019

Не могу запросить от django, где имя поля имеет двойное подчеркивание.Это связано с тем, что в языке запросов django __ имеет свое собственное значение

, так как я могу запросить поле с фактическим именем "my__fyeild__name"?

template.fields.filter(my__fyeild__name="aaa")

В базе данных столбецимеет имя с двумя подчеркиваниями __, и мне запрещено переименовывать этот столбец.

Ответы [ 3 ]

4 голосов
/ 25 сентября 2019

Я не уверен, зачем нам ставить двойное подчеркивание в поле модели.Django использует двойное подчеркивание для поиска.

Из документа Ограничения имени поля

Имя поля не может содержать более одного подчеркивания в строке из-заработает синтаксис поиска запросов Django.Например:

class Example(models.Model):
    foo__bar = models.IntegerField() # 'foo__bar' has two underscores!
3 голосов
/ 25 сентября 2019

Вы не можете, так как Django всегда будет делиться на часть __.Но я думаю, тебе это все равно не нужно.Вы можете определить поле на уровне Django, которое имеет другое имя на уровне базы данных.

Мы можем определить модель, например, с полем, в котором мы указываем имя столбца на уровне базы данных с помощьюdb_column=... параметр [Django-doc] :

class SomeModel(models.Model):
    my_field_name = models.CharField(max_length=128, <b>db_column='my__field__name'</b>)

Так что здесь вы можете запросить на my_field_name, и Django автоматически использует my__field__nameв запросе.

1 голос
/ 25 сентября 2019

Отказ от ответственности: Я саркастичен, когда говорю, что это "решение".Это ужасная идея и, на мой взгляд, никогда не должна быть реализована.Я только показываю это, чтобы добавить ясности к , почему вы не можете добавить __ к столбцам модели, в надежде, что вы пересмотрите проблему под рукой.

Какответ на ответы о том, что вы не можете иметь двойные имена полей подчеркивания:

да, вы можете !

Это просто, просто перейдите кdjango/db/models/constants.py и измените LOOKUP_SEP на все, что вы хотите (для этого примера я буду использовать _some_new_sep_)

Вот несколько примеров:

myapp / models:

from django.db import models

class Foo(models.Model):
    test__col = models.IntegerField()

class Bar(models.Model):
    foo = models.ForeignKey(Foo, related_name='bar', on_delete=models.CASCADE)
    title = models.CharField(max_length=45)

использование:

>>> from myapp.models import Foo, Bar
>>> Foo.objects.create(test__col=1)
<Foo: Foo object (1)>
>>> Bar.objects.create(foo_id=1, title='test')
<Bar: Bar object (1)>
>>>
>>> Foo.objects.filter(bar_some_new_sep_title='test')
<QuerySet [<Foo: Foo object (1)>]>

Существует только один небольшой недостаток , это приведет к тому, что любые сторонние приложения, которые жестко закодируют значение по умолчанию от LOOKUP_SEP до , прервутся .Оказывается, это в значительной степени каждое приложение, которое его использует (включая приложения по умолчанию для django).

Как указано в комментариях WilliamVanOsem:

На самом деле, это очень распространенный феномен: если человек спрашивает «Как сделать Y», то ответ таков: «Во-первых, вы не должны делать Y, вы можете исправить исходную проблему лучше».

...