Использовать текстовый ввод для ModelChoiceField в Django - PullRequest
0 голосов
/ 05 мая 2020

Я бы хотел, чтобы пользователь мог изменить, какой продукт входит в конкретную c позицию заказа. Вот моя модель:

class OrderLineItem(models.Model):
    uuid = models.UUIDField(default=uuid.uuid4, editable=False, unique=True)
    order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='details')
    product = models.ForeignKey(Product, on_delete=models.CASCADE)
    price_before_discounts = models.DecimalField(default=D(0.00), max_digits=7, decimal_places=2)
    discount = models.DecimalField(default=D(0.00), max_digits=7, decimal_places=2)
    has_applied_discount = models.BooleanField(default=False)
    total = models.DecimalField(default=D(0.00), max_digits=7, decimal_places=2)
    line_number = models.IntegerField(default=1)
    added_by_promotion = models.ForeignKey('Promotions.CouponRedemption', on_delete=models.CASCADE, blank=True, null=True, default=None)
    substitute = models.ForeignKey(Product, related_name='substitute', on_delete=models.CASCADE, blank=True, null=True, default=None)

Единственное поле, которое я пытаюсь изменить, - это поле замены. Вот моя форма:

class OrderDetailSubstitutionForm(ModelForm):
    substitute = forms.ModelChoiceField(queryset=Product.objects.all(), widget=forms.TextInput, required=False)
    def __init__(self, *args, **kwargs):
        super(OrderDetailSubstitutionForm, self).__init__(*args, **kwargs)
        self.fields['substitute'].widget.attrs.update({'class':'form-control text-center','style':'width:100%'})
        self.fields['substitute'].label = ""

    class Meta:
        model = OrderLineItem
        fields = ('substitute',)

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

Я попытался переопределить чистый метод для выполнения этого поиска, но он просто продолжает выдавать ошибку «Выберите допустимый выбор. Этот выбор не является одним из доступных вариантов». Кроме того, очищенные данные всегда указывают поле замены как None, даже когда данные передаются.

Вот конкретный c метод очистки, который я пытался использовать.

    def clean_substitute(self):
        print(self.cleaned_data)
        cleaned_data = super().clean()
        print(cleaned_data)
        if cleaned_data.get('substitute', None) is not None:
            try:
                substitute = cleaned_data.get('substitute')
                product = Product.objects.get(sku=substitute)
                return product.id
            except:
                raise forms.ValidationError("Could not find object matching sku: {}".format(substitute))
...