Django Фильтр QuerySet не дает результатов при поиске строки, содержащей точку - PullRequest
1 голос
/ 31 января 2020

Я не уверен, что могу гуглить неправильно или просто не вижу свою ошибку.

Я использую Django 3.x с базой данных postgreSQL со схемой django2.

У меня есть модель в Django, содержащая CharField для сохранения IPv4-адреса. Да, я знаю о GenericIPAddressField и могу переключиться на это.

class APN(models.Model):
    address = models.CharField(max_length=64)
    username= models.CharField(max_length=64, unique=True, primary_key=True)
    password = models.CharField(max_length=64)
    ip = models.CharField(max_length=64)
    responsible_user= models.CharField(max_length=64, null=True)
    assigned = models.BooleanField(default=False)

Теперь я хочу отфильтровать с помощью results_apn = APN.objects.filter(ip__contains=query), где query - строка.

Фильтрация QuerySet на ip__contains=query приводит меня к двум наблюдениям:

  1. при поиске номера без каких-либо точек (например, 100 или 254), тогда я получу все IP-адреса, содержащие эту конкретную строку
  2. при поиске часть IP или полный IP (например, 10.171.16.14 или 17.128), тогда я не получу никаких результатов.

Я получил запрос, который генерирует Django (QuerySet.query):

SELECT "sim_apn"."address", "sim_apn"."username", "sim_apn"."password", "sim_apn"."ip", "sim_apn"."responsible_user", "sim_apn"."assigned" FROM "sim_apn" WHERE "sim_apn"."ip"::text LIKE %10.171.16.14%

Ad Если я буду использовать это непосредственно в SQL, я получу результат. Но Django не хочет дать мне ответ на этот вопрос.

Я что-то упустил или у Django есть проблемы с точками в запросах фильтра?

Заранее спасибо.

1 Ответ

0 голосов
/ 31 января 2020

Есть несколько очевидных вопросов, которые я должен задать, вы уверены, что объекты, которые вы ищете; на самом деле существует?

Как вы сказали, GenericIPAddressField - ваш лучший выбор для хранения IP-адресов

Не думаю, что icontains будет иметь какое-либо значение, но попробуйте.

Если вам нужно срочное исправление, хакерский (не рекомендуемый) способ заставить его работать, разделив IP, отфильтруйте все результаты, содержащие первое число, затем сузьте его и отфильтруйте второе число.

Например: IP 127.67.1.1

ip_split = ['127', '67', '1', '1']

Получить список запросов всех результатов, содержащих ip_split [0] затем отфильтруйте его, если они не содержат остальных фракций ip.

Хаки, но это будет работать, пока вы не найдете Pythoni c способ исправить это.

...