如何最好地从Django模板的for循环中捕获变量 [英] How best to capture variables from within a for-loop in Django template

查看:60
本文介绍了如何最好地从Django模板的for循环中捕获变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个查询集: type age_group .

类型查询集:< QuerySet [<类型:猫>,<类型:狗>,<类型:其他>]>

age_group查询集:< QuerySet [< AgeGroup:Young>,< AgeGroup:Baby>,< AgeGroup:Adult>,< AgeGroup:Senior>]

age_group queryset: <QuerySet [<AgeGroup: Young>, <AgeGroup: Baby>, <AgeGroup: Adult>, <AgeGroup: Senior>]>

我从模板表单中循环访问这些变量,以便在选择了pk时可以获取pk,但无法从for循环中捕获变量.使用Django时,如何从for循环中捕获变量?我想捕获 type 的pk和 age_group 的pk,然后同时使用两者过滤模型 Animal 并返回与用户的匹配的过滤列表首选项.本质上是目录搜索功能.

I loop through these from within my template form so that I can grab the pk when one has been selected, but I cannot capture the variable from within the for loop. How do I capture a variable from within a for loop when using Django? I want to capture pk for type and pk for age_group and then use both to filter the model Animal and return a filtered list that matches the user's preferences. A directory search function, essentially.

模板:

    {% extends 'base.html' %}

    {% block content %}
        <h1>Animal Search</h1>

    <form class="form-inline" action= '.' method="post">
            {% csrf_token %}
       
         <select name= "TypeSearch" class="custom-select my-1 mr-sm-2" id="animal_list_type">
         <label class="sr-only type" for="animal_list_type">SEARCH</label>
             {% for i in animal_type_list %}
                    <option value="{{i.pk}}">{{i}}</option> #how to capture the selected pk??
            {% endfor %}
         </select>

         <select name="AgeSearch" class="custom-select my-1 mr-sm-2" id="animal_list_ageGroup">
         <label class="sr-only ageLabel" for="animal_list_ageGroup">SEARCH</label>
             {% for j in age_group_list %}
                    <option value="{{j.pk}}">{{j}}</option> #how to capture the selected pk??
            {% endfor %}
         </select>

        <input type="submit" value="SEARCH" onclick="window.location='{% url 'animals:matches_list' pk=4 %}'; return false;">
        <input type="submit" onclick="window.location='{% url 'animals:animals' %}'; return false;" value="Cancel">
    </form>

    {% endblock %}
  

views.py

    class VisitorSearchView(View):
    def get(self, request, pk=None):
        #first tried ModelForm but couldn't figure out how to capture and iterate through one field of value options at a time
        animalList = Animal.type.get_queryset()
        animalList2 = Animal.ageGroup.get_queryset()
        context = {
            "animal_type_list": animalList,
            "age_group_list": animalList2
            }

        return render(request, "animals/landing.html", context)

    def post(self, request, pk=None):
        theForm1 = AnimalSearchForm(request.POST)
        success_url = reverse_lazy('animals:matches_list')
        print(pk)
        print(theForm1)
        filler_for_now = Animals.objects.all()
        context = {
                'theMatches': filler_for_now
            }
        return render(request, success_url, context)

model.py

    class Animal(models.Model):
        name = models.CharField(max_length=500, blank=False, null=False)
        type = models.ForeignKey(Type, on_delete=models.SET_NULL, blank=False, null=True)
        ageGroup = models.ForeignKey(AgeGroup, max_length=300, on_delete=models.SET_NULL, blank=False, null=True)
        age = models.PositiveIntegerField(blank=False, null=False)
        sex = models.CharField(max_length=100, choices=SEX, blank=False, null=False, default='NA')
        breedGroup = models.ManyToManyField(BreedGroup, blank=False)
        breed = models.ManyToManyField(Breed, blank=False)
        tagLine = models.CharField(max_length=300, blank=False, null=False)
        goodWithCats = models.BooleanField(blank=False, null=False, default='Not Enough Information')
        goodWithDogs = models.BooleanField(null=False, blank=False, default='Not Enough Information')
        goodWKids = models.BooleanField(null=False, blank=False, default='Not Enough Information')

urls.py

    app_name = 'animals'

urlpatterns = [

    path('', views.AnimalListView.as_view(), name='animals'),
    path('landing/', views.VisitorSearchView.as_view(), name='landing'),
    path('matches/<int:pk>', views.VisitorSearchView.as_view(), name='matches_list'),

]

forms.py#(最初试图使用ModelForm,但无法弄清楚如何为 chooseType chooseAge 字段获取pk,因此选择尝试仅从视图中使用查询集)

forms.py #(originally tried to use ModelForm but couldn't figure out how to grab the pk for both chooseType and chooseAge fields so chose to try to just use querysets from view)

    class AnimalSearchForm(ModelForm):
    chooseType = ModelChoiceField(queryset=Animal.objects.values_list('type', flat=True).distinct(),empty_label=None)
    chooseAge  = ModelChoiceField(queryset=Animal.objects.values_list('ageGroup', flat=True).distinct(), empty_label=None)
    class Meta:
        model = Animal
        exclude = '__all__'

在Django之外,这将是一个简单的问题.使用Django时,如何从for循环中捕获变量?我试图在for循环外部实例化一个变量,然后根据从内部进行的选择来更新该变量,但是似乎无法通过模板来完成...?

Outside of Django, this would be a simple problem to solve. How do I capture a variable from within a for loop when using Django? I have tried to instantiate a variable outside the for-loop and then update that based off selection from within, but it seems that this cannot be done via the template...?

推荐答案

这里的真正问题是,您确实应该使用 FormView DetailView 一起显示表单>以显示模型数据,在这种情况下,您应该执行以下操作:

Well the real issue here is that you really should be using FormView to display a form together with DetailView to display model data, in this particular case you should do something like this:

views.py

from django.views.generic import FormView, DetailView

class VisitorSearchView(FormView, DetailView):
    model = Animal
    template_name = 'animals/landing.html'
    form_class = AnimalSearchForm

    def form_valid(self, form):
        data = form.cleaned_data # Dict of submitted data
        # handle form validation and redirect

    def get_context_data(self, request):
        context = super(VisitorSearchView, self).get_context_data(**kwargs)
        animals = Animal.objects.all() # or use a custom filter
        context['animals'] = animals
        return context

然后在您的 landing.html

您想要动物类型的列表:

{% for animal in animals %}
    {{ animal.type }}
{% endfor %}

以及您要在其中列出动物年龄的列表:

and where you want a list of animal ages:

{% for animal in animals %}
    {{ animal.age }}
{% endfor %}

按通常的方式声明您的表格.

declare your form normally as you would.

这篇关于如何最好地从Django模板的for循环中捕获变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆