Django Filter с использованием Q-объектов на двух моделях
Я работаю над приложением Django, в котором я хочу выполнить поиск в двух моделях Profile (поля surname или othernames) и Account (поле account_number) с помощью Q-объектов. Из того, что я сделал, поиск выполняется только в одной модели (Account), а любая попытка поиска любого значения из другой модели (Profile) вызывает ошибку, которая гласит: Поле 'id' ожидало число, но получило 'Ahile Terdoo'. Смотрите код моей модели:
class Profile(models.Model):
customer = models.OneToOneField(User, on_delete=models.CASCADE, null = True)
surname = models.CharField(max_length=20, null=True)
othernames = models.CharField(max_length=40, null=True)
gender = models.CharField(max_length=6, choices=GENDER, blank=True, null=True)
address = models.CharField(max_length=200, null=True)
phone = models.CharField(max_length=11, null=True)
image = models.ImageField(default='avatar.jpg', blank=False, null=False, upload_to ='profile_images',
)
def __str__(self):
return f'{self.customer.username}-Profile'
class Account(models.Model):
customer = models.OneToOneField(User, on_delete=models.CASCADE, null=True)
account_number = models.CharField(max_length=10, null=True)
date = models.DateTimeField(auto_now_add=True, null=True)
def __str__(self):
return f' {self.customer} - Account No: {self.account_number}'
Вот моя форма:
class SearchCustomerForm(forms.Form):
value = forms.CharField(label = 'Enter Name or Acct. Number', max_length=30)
Вот мои взгляды
def create_account(request):
if searchForm.is_valid():
#Value of search form
value = searchForm.cleaned_data['value']
#Filter Customer by Surname, Othernames , Account Number using Q Objects
user_filter = Q(customer__profile__exact = value) | Q(account_number__exact = value)
#Apply the Customer Object Filter
list_customers = Account.objects.filter(user_filter)
else:
list_customers = Account.objects.order_by('-date')[:8]
Кто-то должен помочь, как лучше осуществлять поиск с использованием Q-объектов на двух моделях.
Не уверен, что правильно понял ваш вопрос, но если вы хотите фильтровать Account на основе фамилии профиля, вам нужно указать это в объекте Q. Напишите объект Q следующим образом
user_filter = Q(customer__profile__surname__exact = value) | Q(account_number__exact = value)
Первичный ключ модели User используется в качестве ключа в моделях Account и Profile.
Фильтр customer__profile
на модели Account следует за отношениями от моделей Account к User и Profile, используя этот ключ. Поэтому ожидается, что поле customer
будет содержать числовой идентификатор. __str__
выполняется на стороне python, а фильтры используются на стороне db, поэтому он не заменяет числовой id на имя пользователя.
По соглашению, поле, определяющее связь с другой моделью, должно быть названо в честь модели в нижнем регистре. Таким образом, customer
должно быть user
, но можно использовать другое имя, если вам так больше нравится.
Попробуйте фильтровать по customer__username
вместо customer__profile
.
Для фильтрации по фамилии попробуйте customer__profile__surname
. Он должен следовать взаимосвязи от аккаунта к пользователю, используя определенное вами поле customer
. Затем в обратном направлении от User к Profile, используя имя модели в нижнем регистре (profile
).