gpt4 book ai didi

django - 使用 MultipleChoiceFilter 时动态重新加载选择

转载 作者:行者123 更新时间:2023-12-03 21:32:31 25 4
gpt4 key购买 nike

我正在尝试构建一个 MultipleChoiceFilter其中选项是存在于相关模型 ( DatedResource ) 上的一组可能日期。

到目前为止,这是我正在使用的...

resource_date = filters.MultipleChoiceFilter(
field_name='dated_resource__date',
choices=[
(d, d.strftime('%Y-%m-%d')) for d in
sorted(resource_models.DatedResource.objects.all().values_list('date', flat=True).distinct())
],
label="Resource Date"
)

当它显示在 html View 中时...

enter image description here

这起初工作正常,但是如果我创建新的 DatedResource具有新的不同的对象 date我需要重新启动我的网络服务器,以便它们在此过滤器中被选为有效选择。我相信这是因为 choices列表在网络服务器启动时评估一次,而不是每次我的页面加载时评估。

有没有办法解决这个问题?也许通过一些创造性的使用 ModelMultipleChoiceFilter ?

谢谢!

编辑:
我尝试了一些简单的 ModelMultipleChoice用法,但遇到一些问题。
resource_date = filters.ModelMultipleChoiceFilter(
field_name='dated_resource__date',
queryset=resource_models.DatedResource.objects.all().values_list('date', flat=True).order_by('date').distinct(),
label="Resource Date"
)

HTML 表单显示得很好,但是这些选项不是过滤器接受的值。我收到 "2019-04-03" is not a valid value.验证错误,我假设是因为这个过滤器期待 datetime.date对象。我想过使用 coerce参数,但是这些在 ModelMultipleChoice 中不被接受过滤器。

根据 dirkgroten 的评论,我尝试使用 linked question 中的建议.这最终是这样的
resource_date = filters.ModelMultipleChoiceFilter(
field_name='dated_resource__date',
to_field_name='date',
queryset=resource_models.DatedResource.objects.all(),
label="Resource Date"
)

这也不是我想要的,因为 HTML now 表单现在是 a) 显示 str每个的代表 DatedResource , 而不是 DatedResource.date字段和 b)它们不是唯一的(例如,如果我有两个具有相同 DatedResource 的对象 date ,它们的两个 str 表示都出现在列表中。这也是不可持续的,因为我有 200k+ DatedResources ,和尝试加载所有日期时页面挂起(与 values_list 过滤器相比,它能够在几秒钟内拉出所有不同的日期。

最佳答案

一种简单的解决方案是 覆盖 __init__() filterset 类的方法 .

from django_filters import filters, filterset


class FooFilter(filterset.FilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
try:
self.filters['user'].extra['choices'] = [(d, d.strftime('%Y-%m-%d')) for d in sorted(
resource_models.DatedResource.objects.all().values_list('date', flat=True).distinct())]
except (KeyError, AttributeError):
pass


resource_date = filters.MultipleChoiceFilter(field_name='dated_resource__date', choices=[], label="Resource Date")

注意:提供 choices=[] 在 filterset 类的字段定义中

结果

我使用以下依赖项测试并验证了此解决方案
1. Python 3.6
2. Django 2.1
3. DRF 3.8.2
4. Django 过滤器 2.0.0
我使用以下代码来重现行为
# models.py
from django.db import models


class Musician(models.Model):
name = models.CharField(max_length=50)

def __str__(self):
return f'{self.name}'


class Album(models.Model):
artist = models.ForeignKey(Musician, on_delete=models.CASCADE)
name = models.CharField(max_length=100)
release_date = models.DateField()

def __str__(self):
return f'{self.name} : {self.artist}'


# serializers.py
from rest_framework import serializers


class AlbumSerializer(serializers.ModelSerializer):
artist = serializers.StringRelatedField()

class Meta:
fields = '__all__'
model = Album


# filters.py
from django_filters import rest_framework as filters


class AlbumFilter(filters.FilterSet):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters['release_date'].extra['choices'] = self.get_album_filter_choices()

def get_album_filter_choices(self):
release_date_list = Album.objects.values_list('release_date', flat=True).distinct()
return [(date, date) for date in release_date_list]

release_date = filters.MultipleChoiceFilter(choices=[])

class Meta:
model = Album
fields = ('release_date',)


# views.py
from rest_framework.viewsets import ModelViewSet
from django_filters import rest_framework as filters


class AlbumViewset(ModelViewSet):
serializer_class = AlbumSerializer
queryset = Album.objects.all()
filter_backends = (filters.DjangoFilterBackend,)
filter_class = AlbumFilter

我在这里使用了 django-filter DRF .
现在,我通过 Django 管理控制台填充了一些数据。之后,专辑api变成如下,
Album-List API Result
我得到了 release_date 作为
DateChoices Before
然后, I added new entry through Django admin -- (Screenshot)我刷新了 DRF API 端点,可能的选择如下,
New Choice in FilterList

关于django - 使用 MultipleChoiceFilter 时动态重新加载选择,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55496921/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com