首页 > 解决方案 > Django 过滤器:如何根据另一个 Modelchoicefilter 输入缩小 ModelChoicefilter 选项

问题描述

我想知道当用户从 Categoryfilter 中选择一个选项时,是否可以缩小我的 Subcategoryfilter 的选择范围。我基本上希望我的子类别在选择特定类别时减少其选项。目前,当我渲染 {{filter.form.subcategory}} 时,我得到每个类别的所有子类别,而不是选择的特定类别

意见

class ProductSearch(ListView):
    model = Product
    template_name = "products/ad-list-view.html"
    paginate_by = 1

    def get_context_data(self, **kwargs):
        context = super(ProductSearch, self).get_context_data(**kwargs)
        Product_list = super().get_queryset(**kwargs)

        get_copy = self.request.GET.copy()
        parameters = get_copy.pop('page', True) and get_copy.urlencode()

        context.update({
            'filter': ProductFilter(
                self.request.GET, queryset=Product_list),
            'parameters': parameters
        })

        return context

    def get_queryset(self):

        Product_list = super().get_queryset()

        return ProductFilter(self.request.GET, queryset=Product_list).qs


过滤器.py

options = (
    ("Brand_new", "Brand New"),
    ("like_new", "Like New"),
    ("Used", "Used"),
    ("very_used", "Very New"),
    ("fair", "Fair Condition"),
)


class ProductFilter(django_filters.FilterSet):

    q = django_filters.CharFilter(widget=forms.TextInput(attrs={'class': 'form-control my-2 my-lg-0', 'id': "inputtext4", 'placeholder': 'What are you looking for'}),
                                  method='my_custom_filter',
                                  label="Search")

    category = django_filters.ModelChoiceFilter(
        queryset=Category.objects.all(), empty_label="Category",
        widget=forms.Select(
            attrs={'class': "w-100 form-control mt-lg-1 mt-md-2", 'id': "inputCategory4", }),
    )
    subcategory = django_filters.ModelChoiceFilter(
        queryset=SubCategory.objects.all(), widget=forms.CheckboxSelectMultiple(attrs={'onclick': 'this.form.submit()'}))

    condition = django_filters.MultipleChoiceFilter(
        choices=options, widget=forms.CheckboxSelectMultiple(attrs={'onclick': 'this.form.submit()'}))

    price = django_filters.NumericRangeFilter()

    lowest = django_filters.OrderingFilter(choices=(('price', 'low to high'), ('-price', 'high to low'))
                                          
                                           )

     
    class Meta:
        model = Product
        fields = {
            'category': ['in'],
            'condition': ['icontains', ],
            'price': ['contains'],
        }

    def my_custom_filter(self, queryset, name, value):
        return Product.objects.filter(
            Q(Product_name__icontains=value)
        )

    def Low_to_highFilter(self, queryset, name, value):
        return Product.objects.order_by("-price")

楷模

class Category(models.Model):
    Name = models.CharField(max_length=50, unique=True)

    def __str__(self):
        return self.Name


class SubCategory(models.Model):
    Name = models.CharField(max_length=200)
    Category = models.ForeignKey(
        Category, related_name="subcat", on_delete=models.CASCADE)

    class Meta:
        ordering = ["Category", ]

    def __str__(self):
        return f"{self.Category.Name} / {self.Name}"


class Product(models.Model):
    options = (
        ("Brand_new", "Brand New"),
        ("like_new", "Like New"),
        ("Used", "Used"),
        ("very_used", "Very New"),
        ("fair", "Fair Condition"),
    )
    Owner = ForeignKey(Profile, on_delete=models.CASCADE, default=1,
                       blank=True, null=True, related_name="products")
    category = ForeignKey(
        Category, blank=True, default=None, on_delete=models.CASCADE)
    subcategory = models.ForeignKey(
        SubCategory, related_name="product", on_delete=models.CASCADE)
    Product_name = models.CharField(max_length=50, null=True, blank=True)
    Image = models.ImageField(max_length=50, null=True,
                              blank=True, upload_to="users/products-images",)
    Short_des = models.CharField(max_length=50, null=True, blank=True)
    Description = models.TextField(max_length=500, null=True, blank=True)
    Manufacturer = models.CharField(
        max_length=50, null=True, blank=True, default='-')
    model = models.CharField(max_length=50, null=True,
                             blank=True, default='-')
    youtube_link = models.URLField(null=True, blank=True)
    price = models.IntegerField()
    condition = models.CharField(
        choices=options, max_length=50, null=True, blank=True)
    favourites = ManyToManyField(
        Profile, related_name="favourites", default=None, blank=True)
    archived = models.BooleanField(default=False)
    in_stock = models.BooleanField(default=True)
    is_active = models.BooleanField(default=True)
    location = models.CharField(max_length=50, null=True, blank=True)
    created = models.DateTimeField(auto_now_add=True)
    id = models.UUIDField(default=uuid.uuid4, unique=True,
                          primary_key=True, editable=False)

    class Meta:
        ordering = ('-created',)

    def __str__(self):
        return self.Product_name

标签: pythondjango-filterdjango-filters

解决方案


推荐阅读