简体   繁体   中英

Having trouble saving django forms to sqlite

I am currently working on a program which is currently in development. Now I have never worked with Django before this and I am having some troubles.

I am trying to save a few form fields to a sqlite database however I am getting errors.

Here is the error that I get

ValueError at /recipes
The view brewery.views.recipes didn't return an HttpResponse object. It returned None instead.
Request Method: POST
Request URL:    http://localhost:8000/recipes
Django Version: 4.0.2
Exception Type: ValueError
Exception Value:    
The view brewery.views.recipes didn't return an HttpResponse object. It returned None instead.
Exception Location: C:\Users\Admin\AppData\Roaming\Python\Python310\site-packages\django\core\handlers\base.py, line 309, in check_response
Python Executable:  C:\Program Files\Python310\python.exe
Python Version: 3.10.2
Python Path:    
['C:\\Users\\Admin\\Desktop\\praktika\\brew',
 'C:\\Program Files\\Python310\\python310.zip',
 'C:\\Program Files\\Python310\\DLLs',
 'C:\\Program Files\\Python310\\lib',
 'C:\\Program Files\\Python310',
 'C:\\Users\\Admin\\AppData\\Roaming\\Python\\Python310\\site-packages',
 'C:\\Program Files\\Python310\\lib\\site-packages',
 '/home/ponasniekas/wwwpi/brew',
 '/home/ponasniekas/wwwpi/brew/brew',
 '/home/ponasniekas/wwwpi/brew/brew/brewery',
 '/home/ponasniekas/.local/lib/python3.8/site-packages']

Here is my views file:

from django.http import HttpResponse
import json
from django.http import StreamingHttpResponse
from django.shortcuts import render
from django.core.serializers import serialize
from django.http import JsonResponse
from django.template import RequestContext


from .models import StockYeast, queryset_to_indexlist,queryset_to_array, Brew, Fermentable, Miscs, RecipeYeast, Recipes, Yeast,StockFermentables
from .models import Hop,StockHop,StockMiscs

from .forms import RecipeForm, RecipeFermentableForm, RecipeHopForm, RecipeMiscForm,RecipeWaterForm, RecipeYeastForm,RecipeMashForm, StockMiscForm
from .forms import StockFermentableForm,StockHopForm,StockYeastForm, StockMiscForm
from django.forms import formset_factory

def index(request):
    return render(request, 'index.html')

def recipes(request):
    if request.method == 'POST':
        recipes = RecipeForm(request.POST)
        
        if form.is_valid():
            n = form.cleaned_data["name"]
            t = Recipes(name=n)
            t.save()
        
        else:
            recipes = Recipes.objects.all()
            recipeFermentableFormset = formset_factory(RecipeFermentableForm, extra=1)
            recipeHopFormset = formset_factory(RecipeHopForm, extra=1)
            RecipeMiscFormSet= formset_factory(RecipeMiscForm, extra=1)
            RecipeYeastFormSet = formset_factory(RecipeYeastForm,extra=1)
            RecipeMashFormSet = formset_factory(RecipeMashForm,extra=1)
            context = {
                "recipes" : recipes,
                "recipe_form" : RecipeForm(auto_id="recipe_%s"),
                "recipe_fermentableformset":recipeFermentableFormset(prefix='fermentable'),
                "recipe_hopformset":recipeHopFormset(prefix='hop'),
                "recipe_miscformset":RecipeMiscFormSet(prefix='misc'),
                "recipe_yeastformset":RecipeYeastFormSet(prefix='yeast'),
                "recipe_mashformset" :RecipeMashFormSet(prefix='mash'),
                "recipeWaterForm":RecipeWaterForm()
            }
            return render(request, 'recipes.html', context)

And here is my recipes.html file:

{% block content %}
<!-- Modal -->

<div class="card shadow-sm">
    <div class="card-header" id="headingOne">
        <h5 class="mb-0"> Receptas</h5>

    </div>

    <div id="card-base" class="collapse show" aria-labelledby="headingOne" data-parent="#accordion">
        <div class="card-body">
            <div class="row">
                <div class="col">
                    <form method="post" action="/recipes">
                        {% csrf_token %}
                        {{recipe_form.ibu}}
                        {{recipe_form.abv}}
                        <div class="row">
                            <div class="col">{{recipe_form.name|as_crispy_field}}</div>
                            <div class="col">{{recipe_form.style|as_crispy_field}}</div>
                        </div>

                        <div class="row">
                            <div class="col">{{recipe_form.batch_size|as_crispy_field}}</div>
                            <div class="col">{{recipe_form.boile_time|as_crispy_field}}</div>
                            <div class="col">{{recipe_form.efficiency|as_crispy_field}}</div>
                        </div>
                        <div class="row">
                            <div class="col">{{recipe_form.primary_age|as_crispy_field}}</div>
                            <div class="col">{{recipe_form.secondary_age|as_crispy_field}}</div>
                            <div class="col">{{recipe_form.age|as_crispy_field}}</div>
                        </div>
                        <div class="row">
                            <div class="col">{{recipe_form.pub_date|as_crispy_field}}</div>
                        </div>
                        <div class="row">
                            <div class="col">{{recipe_form.notes|as_crispy_field}}</div>
                        </div>
                </div>

                <span class="d-flex flex-row-reverse"><button class="btn btn-secondary" id="save_recipe_btn"
                        type="submit"><i class="bi bi-save"></i></br> Saugoti</button></span>
                </form>
            </div>
        </div>
    </div>
</div>
{% endblock %}

Here is my models.py file:

class Recipes(models.Model):
    name = models.CharField(max_length=120, default='')
    pub_date = models.DateTimeField('date published')
    style = models.CharField(max_length=200, default='')
    brewer = models.CharField(max_length=100, default='')
    type = models.CharField(max_length=20, default='All Grain')
    version = models.CharField(max_length=20, default='1')
    batch_size = models.DecimalField(decimal_places=2, max_digits=8, default=0.0)
    boil_size = models.DecimalField(decimal_places=2, max_digits=8, default=0.0)
    boil_time = models.DecimalField(decimal_places=1, max_digits=4, default=0.0)
    efficiency = models.DecimalField(decimal_places=1, max_digits=4, default=75.0)
    ibu = models.DecimalField(decimal_places=1, max_digits=4, default=0.0)
    abv = models.DecimalField(decimal_places=2, max_digits=4, default=0.0)
    notes = models.TextField(default='')
    carbonation = models.DecimalField(decimal_places=2, max_digits=4, default=0.0)
    primary_age = models.DecimalField(decimal_places=1, max_digits=4, default = 0)
    secondary_age = models.DecimalField(decimal_places=1, max_digits=4, default = 0)
    age = models.DecimalField(decimal_places=1, max_digits=4, default = 0)
    __fermentables = []
  
    @classmethod
    def create(cls,attr):
        recipe = cls()
        # do something with the book
        for k in Recipes._meta.fields:
            if  k.name in attr:
                setattr(recipe,k.name,attr[k.name])
        return recipe
    @classmethod
    def addFermentables(self,items):

       for itm in items:
           
           self.__fermentables.append(itm)
         
           return self.__fermentables

    @classmethod
    def addHops(self,items):
       for i in items:
           return i

    @classmethod
    def addYeast(self,items):
       for i in items:
           return i

    @classmethod
    def addMashStep(self,items):
       for i in items:
           return i
           

  
class RecipeFermentable(models.Model):
    recipe = models.ForeignKey(Recipes, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, default='')
    amount = models.DecimalField(decimal_places=2, max_digits=8, default=0.0)
    extract = models.DecimalField(decimal_places=1, max_digits=8, default=0.0)
    type = models.CharField(max_length=20, default='')
    color= models.DecimalField(decimal_places=1, max_digits=8, default=0.0)
    fermentable = models.ForeignKey(Fermentable, on_delete=models.RESTRICT)
    def create(cls, attr, recipes):
        fermentables = cls()
        # do something with the book
        for k in RecipeFermentable._meta.fields:
            if  k.name in attr:
                setattr(recipe,k.name,attr[k.name])
        return fermentables

class RecipeHops(models.Model):
    recipe = models.ForeignKey(Recipes, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, default='')
    alpha = models.DecimalField(decimal_places=1, max_digits=4, default=0.0)
    amount = models.DecimalField(decimal_places=2, max_digits=8, default=0.0)
    use = models.CharField(max_length=10, default='')
    hop = models.ForeignKey(Hop, on_delete=models.RESTRICT)
    time = models.DecimalField(decimal_places=1, max_digits=4, default=0.0)

Here is my forms file:

from django import forms
from tempus_dominus.widgets import DatePicker
from .models import Fermentable, Hop, Yeast, Miscs,queryset_to_indexlist 
from django.db import models
import json
import datetime
class RecipeForm(forms.Form):
    recipe = forms.CharField(widget=forms.HiddenInput())
    ibu  = forms.CharField(widget=forms.HiddenInput())
    abv  = forms.CharField(widget=forms.HiddenInput())
    name = forms.CharField(label="Recepto pavadinimas",
        widget=forms.TextInput(attrs={}),
        max_length=80,
        required=True,
        localize=False,
        disabled=False,
        help_text="")
    style = forms.CharField(label="Stilius",
        widget=forms.TextInput(attrs={}),
        max_length=80,
        required=True,
        localize=False,
        disabled=False,
        help_text="")
   
    pub_date = forms.DateField(label="Data:",
         
        initial = datetime.datetime.today,
        widget = DatePicker(
            options={
                'minDate': '2009-01-01',
                'maxDate': '2050-12-31',
            },)
        )
    batch_size = forms.CharField(label="Kiekis:",
        widget=forms.TextInput(attrs={}),
        max_length=80,
        initial="1000",
        required=True,
        localize=False,
        disabled=False,
        help_text="")

    efficiency = forms.CharField(label="Efektyvumas",
        widget=forms.TextInput(attrs={}),
        max_length=80,
        initial="85",
        required=True,
        localize=False,
        disabled=False,
        help_text="")

    boile_time = forms.CharField(label="Virimo laikas",
        widget=forms.TextInput(attrs={}),
        max_length=80,
        initial="90",
        required=True,
        localize=False,
        disabled=False,
        help_text="")
    carbonation  = forms.CharField(label="Virimo laikas",
        widget=forms.TextInput(attrs={}),
        max_length=80,
        initial="90",
        required=True,
        localize=False,
        disabled=False,
        help_text="")
    primary_age = forms.CharField(label="Fermentacijos laikas (I)", widget=forms.TextInput(attrs={}))
    secondary_age = forms.CharField(label="Fermentacijos laikas (II)", widget=forms.TextInput(attrs={}))
    age = forms.CharField(label="Brandinimo laikas", widget=forms.TextInput(attrs={}))
    notes = forms.CharField(label="Pastabos", widget=forms.TextInput(attrs={}))

I did everything while watching some tutorial and I feel like I did everything correct however, it doesn't seem to be working.

Could anybody tell me what I did wrong here? Please keep in mind that this is going to be a many to one relationship with recipes and recipefermentables, recipehops and so on. However, for starters I am trying to save just the basic portion of recipe.

You have a typo error in your views.py

def recipes(request):
    if request.method == 'POST':
        form = RecipeForm(request.POST) <------ change recipes to form or use recipes in below form valid and cleaned_data
    
        if form.is_valid():
            n = form.cleaned_data["name"]
            t = Recipes(name=n)
            t.save()

Now I get a different error ValueError at /recipes

This means that you have not returned anything HttpResponse after recipe is saved. So either return HttpResponse or redirect anywhere you want after recipe data created successfully.

from django.http import HttpResponse

def recipes(request):
    if request.method == 'POST':
        form = RecipeForm(request.POST)
    
        if form.is_valid():
            n = form.cleaned_data["name"]
            t = Recipes(name=n)
            t.save()
            # Return a "created" (201) response code.
            return HttpResponse('Recipe Saved Sucessfully', status=201)

If you don't want to add anything after form validation then you can directly save your data as

if form.is_valid():
    form.save()
    # Return a "created" (201) response code.
    return HttpResponse('Recipe Saved Sucessfully', status=201)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM