gpt4 book ai didi

django - 如何将两个查询混合为一个作为下拉元素

转载 作者:行者123 更新时间:2023-12-03 18:59:38 27 4
gpt4 key购买 nike

我需要加入并传递两个类别和子类别查询作为自动完成 select2 下拉列表的元素作为我的 django 表单字段,如下所示:
enter image description here
这是我的表格:

class CategoriesAutocomplete(autocomplete.Select2QuerySetView):
def get_queryset(self):
if not self.request.user.is_authenticated:
return Categories.objects.none()
qs = Categories.objects.all()
if self.q:
qs = qs.filter(Q(name__icontains=self.q))
return qs

def get_result_label(self, item):
return format_html( item.name)


class categories_form(forms.ModelForm):
categories = forms.ModelChoiceField(
queryset= Categories.objects.none(),
widget= autocomplete.ModelSelect2(
url='load_categories',
attrs={
'data-placeholder': 'Select a category',
'data-html': True,
'style': 'min-width: 15em !important;',
}
)
)

class Meta:
model = Post
fields = ['categories']

def __init__(self, *args, **kwargs):
super(category_form, self).__init__(*args, **kwargs)
self.fields['categories'].queryset = Categories.objects.all()
并在网址中:
path('ajax/categories-autocomplete', CategoriesAutocomplete.as_view(), name='load_categories'),
对于类别模型:
class Categories(models.Model):
name = models.CharField(max_length=100)
brief = models.TextField(null=True)
slug = models.SlugField(max_length=200)
date = models.DateTimeField(default=timezone.now)

class Meta:
db_table = "categories"
对于子类别模型:
class Sub_Categories(models.Model):
name = models.CharField(max_length=100)
brief = models.TextField(null=True)
slug = models.SlugField(max_length=200)
date = models.DateTimeField(default=timezone.now)

class Meta:
db_table = "sub_categories"
将类别与子类别连接起来的模型:
class Categories_Sub_Categories(models.Model):
category = models.OneToOneField(Categories, primary_key=True, on_delete=models.CASCADE)
sub_cat = models.OneToOneField(Sub_Categories, on_delete=models.CASCADE)

class Meta:
db_table = "categories_sub-categories"
并在 Post 模型中:
class Post(models.Model):
title = models.CharField(max_length=50)
descript = HTMLField(blank=True, null=True)
categories = models.ForeignKey(Categories, blank=True, null=True, on_delete=models.CASCADE)
subcategories = models.ForeignKey(Sub_Categories, blank=True, null=True, on_delete=models.CASCADE)
author = models.ForeignKey(User, on_delete=models.CASCADE)
date = models.DateTimeField(default=timezone.now)
更新:
@ha-neul 提供的答案正在工作,只是存在一个错误。我用一个例子来展示它:
这是下拉列表中的期望:
**Asia**
China
Malaysia
India
Tajikistan
Iran
Qatar

**Europe**
Germany
Italy
Spain
Netherlands
France

**Africa**
Gana
...
但这就是我所看到的:
    **Asia**
China
Malaysia

**Europe**
Netherlands
France
Sweden
Norway

**Asia**
India
Tajikistan
Iran



**Europe**
Germany
Italy

**Asia**
Qatar

**Africa**
Gana
...

**America**
....

**Europe**
Spain
在 SubCategory 表中,我有类似的内容:
 id ........... category_id
1 1
2 1
3 1
4 1
5 3
6 1
7 2
我正在关注 this包裹。任何让我更接近解决方案的想法将不胜感激!!

最佳答案

如果这是您想要实现的目标,那么:
enter image description here
简短的回答是你应该

  • 让您的子类别与 ForeignKeyField指的是
    类别模型。
  • 使用 Select2GroupQuerySetView 而不是 Select2QuerySetView .

  • 但是实现起来有点复杂。
    首先,虽然 django-autocomplete-light's source codeSelect2GroupQuerySetView ,不知何故你不能把它当作 autocomplete.Select2GroupQuerySetView .所以,你必须在自己的 views.py 中写同样的东西.另外,源代码有错别字,需要修复。
    步骤 1. 在 models.py 中:
    class Category(models.Model):
    name = models.CharField(max_length=100)
    brief = models.TextField(null=True)
    slug = models.SlugField(max_length=200)
    date = models.DateTimeField(default=timezone.now)

    class SubCategory(models.Model):

    ##################
    #You need add this line, so there is a one-to-many relationship

    category = models.ForeignKey(Category, on_delete=models.CASCADE,
    related_name='subcategories')

    ###############

    name = models.CharField(max_length=100)
    brief = models.TextField(null=True)
    slug = models.SlugField(max_length=200)
    date = models.DateTimeField(default=timezone.now)

    Step2.in views.py 复制粘贴 Select2GroupQuerySetView 代码并修复拼写错误
    # import collections, so Select2GroupQuerySetView can work

    import collections

    class Select2GroupQuerySetView(autocomplete.Select2QuerySetView):

    group_by_related = None
    related_field_name = 'name'

    def get_results(self, context):

    if not self.group_by_related:
    raise ImproperlyConfigured("Missing group_by_related.")

    groups = collections.OrderedDict()

    object_list = context['object_list']

    print(object_list)
    object_list = object_list.annotate(
    group_name=F(f'{self.group_by_related}__{self.related_field_name}'))

    for result in object_list:
    group_name = getattr(result, 'group_name')
    groups.setdefault(group_name, [])
    groups[group_name].append(result)

    return [{
    'id': None,
    'text': group,
    'children': [{
    'id': result.id,
    'text': getattr(result, self.related_field_name),

    # this is the line I had to comment out
    #'title': result.descricao
    } for result in results]
    } for group, results in groups.items()]

    3. 使用 Select2GroupQuerySetView 编写自己的 View
    class SubCategoryAutocomplete(Select2GroupQuerySetView):
    print('under subcategory autocomplete')

    group_by_related = 'category' # this is the fieldname of ForeignKey
    related_field_name = 'name' # this is the fieldname that you want to show.

    def get_queryset(self):
    ##### Here is what you normally put... I am showing the minimum code.

    qs = SubCategory.objects.all()

    if self.q:
    qs = qs.filter(name__istartswith=self.q)

    return qs

    如何在您的项目中使用此 View ?
    1. 假设您有一个 Post模型如下,子类别作为外键。
    class Post(models.Model):
    title = models.CharField(max_length=100)

    subcategory = models.ForeignKey(SubCategory,on_delete=models.CASCADE)

    def __str__(self):
    return self.title

    2. 您将生成一个包含子类别自动完成字段的 PostForm。
    在forms.py中
    from django.conf.urls import url

    class PostForm(forms.ModelForm):

    subcategory = forms.ModelChoiceField(
    queryset=Subcategory.objects.all(),

    widget=autocomplete.ModelSelect2(url='subcategory-autocomplete')
    )

    class Meta:
    model= Post
    fields = ('title','subcategory')

  • 您将生成一个 CreatePostView使用通用 CreateView
  • from django.views.generic.edit import CreateView

    class CreatePostView(CreateView):
    model=Post
    template_name='yourapp/yourtemplate.html'# need to change

    form_class=PostForm
    success_url = '/'
  • 现在,在您的 urls.py 中,CreatePostView 的一个 url另一个用于自动完成 View 。
  • urlpatterns = [
    url(
    r'^subcategory-autocomplete/$',
    SubCategoryAutocomplete.as_view(),
    name='subcategory-autocomplete',
    ),
    path('post/create',CreatePostView.as_view(), name='create_post'),
  • 一切就绪,您将前往post/create并查看带有子类别自动完成字段的 PostForm。
  • 使用上面的代码后,OP 出现了奇怪的分组行为。在他的评论中,他提到:

  • Added a .order_by(category_id')` to the qs and fixed it.

    关于django - 如何将两个查询混合为一个作为下拉元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65178429/

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