用户如何使用所选值?

2024-09-30 00:34:07 发布

您现在位置:Python中文网/ 问答频道 /正文

我想允许用户从数据库中选择狗粮品牌。当他选择它时,我想使用他提交的值,并返回给他它有多少卡路里。我被卡住了,不知道下一步该怎么办

models.py

class DogFoodDry(models.Model):
    brand = models.CharField(max_length=25)
    name = models.CharField(max_length=100)
    calories_per_kg = models.IntegerField(null=False)

这是更新后的URL.py:

urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name="index"),
path('dogs', views.results, name="results"),
path('add_dog', views.AddDogView.as_view(), name="add_dog"),
path('dogs/<int:id>', views.DogInfoView.as_view(), name="dog_info"),
path('<str:brand>/<str:name>', views.show_dry, name='form_food_selected'),
path('', views.show_dry, name='form_no_select'),]

这是更新后的forms.py:

class DogFoodDryForm(forms.Form):
    brand = forms.CharField(max_length=25)
    name = forms.CharField(max_length=100)
    calories_per_kg = forms.IntegerField()

这是更新后的views.py:

class DogInfoView(View):
    def get(self, request, id):
        dog = Dog.objects.get(id=id)
        rer = 70*dog.weight**0.75
        context = {'dog':dog, 'rer':rer}
        return render(request, 'dog_info.html', context)

def show_dry(request, brand=None, name=None):
    if request.method == "POST":
        form = DogFoodSelectionForm(request.POST)
        if form.is_valid():
            dogfooddry =  DogFoodDry.objects.get(pk=form.cleaned_data["brand"])
            return redirect("dogfood:form_food_selected", dogfooddry.brand, dogfooddry.name)
    else:
        form = DogFoodSelectionForm()

    if brand and name:
        try:
            dogfooddry = DogFoodDry.objects.get(brand=brand, name=name)
        except DogFoodDry.DoesNotExist:
            dogfooddry = None
    else:
        dogfooddry = None

    context = {'form':form, 'dogfooddry': dogfooddry}

    return render(request, 'dogfood/dog_info.html', context)

这是更新后的dog_info.html

<form method="POST">
    {% csrf_token %} {{ form }}
    <input type="submit" , value="Select">
</form>

{% if dogfooddry %}
<div>
    <strong>{{ dogfooddry.brand }} - {{ dogfooddry.name }}</strong><br/> {{ dogfooddry.calories_per_kg }} calories per kg.
</div>
{% endif %}

Tags: pathnamepyformmodelsrequestformslength
1条回答
网友
1楼 · 发布于 2024-09-30 00:34:07

这里有一条路。你的问题在一些细节上是模糊的,所以我会做一些假设。我为我的应用程序命名为“狗粮”

models.py这里没有什么大问题,可能想帮自己一个忙,添加一个def __str__(参见https://docs.djangoproject.com/en/3.1/ref/models/instances/#str

from django.db import models

class DogFoodDry(models.Model):
    brand = models.CharField(max_length=25)
    name = models.CharField(max_length=100)
    calories_per_kg = models.IntegerField(null=False)

你没有提供urls.py,所以我在这里制作一个。记住还有其他方法,但这是一种方法。我们有两种途径,一种是在url上有品牌和名称时处理,如/purina/kibbles,另一种是在没有品牌和名称时处理。两者都导致了相同的观点

urls.py

from django.urls import path
from . import views

app_name = 'dogfood'

urlpatterns = [
    path('<str:brand>/<str:name>', views.show_dry, name='form_food_selected'),
    path('', views.show_dry, name='form_no_select'),
]

对于表单,如果您只是想选择一个品牌,那么您可能需要一个未绑定的表单,但是其他人可以用另一种方式来实现。在这里,我们设置表单,然后在表单的每个实例化上加载一些选项(这确保在添加更多品牌时重新加载您的选项列表)。我们通过构建一个包含pk和字符串的元组列表,将选项放入brand_choices。我可能会在生产中使用另一种方法,因为我不喜欢以这种方式公开id,但出于演示目的,它可能是好的

forms.py

from django import forms

from dogfood.models import DogFoodDry


class DogFoodSelectionForm(forms.Form):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        brand_choices = [(df.pk, f"{df.brand} | {df.name}") for df in DogFoodDry.objects.all()]

        self.fields['brand'] = forms.ChoiceField(label='Select a brand',
                                                 choices=brand_choices,
                                                 )

我通常不在表单上使用“get”方法。在这种情况下可能没问题,但我将使用基于函数的视图,在提交时使用POST请求。本质上,它为brandname设置一些None默认值,检查这是否是POST请求,以及表单是否有效(https://docs.djangoproject.com/en/3.1/ref/forms/api/#django.forms.Form.is_valid),在选择框中查找由id选择的狗粮。然后它将重定向到指定的url路径,提供该url的预期变量。如果不是帖子,我们会加载一个空表单。try尝试在DogFoodDry模型中查找具有此品牌和名称的条目。这允许您使用get请求直接登录到类似/mybrand/myname的url,并且仍然可以工作。我们构建上下文并呈现模板

views.py

from django.shortcuts import render, redirect

from dogfood.forms import DogFoodSelectionForm
from dogfood.models import DogFoodDry


def show_dry(request, brand=None, name=None):
    if request.method == "POST":
        form = DogFoodSelectionForm(request.POST)
        if form.is_valid():
            dogfooddry = DogFoodDry.objects.get(pk=form.cleaned_data['brand'])
            return redirect('dogfood:form_food_selected', dogfooddry.brand, dogfooddry.name)
    else:
        form = DogFoodSelectionForm()

    if brand and name:
        try:
            dogfooddry = DogFoodDry.objects.get(brand=brand, name=name)
        except DogFoodDry.DoesNotExist:
            dogfooddry = None
    else:
        dogfooddry = None

    context = {'form': form,
               'dogfooddry': dogfooddry}

    return render(request, 'dogfood/dog_info.html', context)

最后但并非最不重要的是您的html模板。我将省去样板html,并为您提供所需的部分。我已经很长时间没有使用非酥皮食品了,但你可以在这里看到一种方法。在表单之后,如果我们知道,我们会显示食物的详细信息(如果他们在url中直接进入带有品牌和名称的url,或者如果我们选择了一个品牌并在视图中重定向到带有品牌和名称的url,我们会这样做)。我建议您阅读文档(https://docs.djangoproject.com/en/3.1/ref/csrf/#how-to-use-it)中的csrf_令牌

dog_info.html

<form method="POST">
    {% csrf_token %}
    {{ form }}
    <input type="submit" value="Select">
</form>

{% if dogfooddry %}
<div>
  <strong>{{ dogfooddry.brand }} - {{ dogfooddry.name }}</strong><br />
  {{ dogfooddry.calories_per_kg }} calories per kg.
</div>
{% endif %}

相关问题 更多 >

    热门问题