Home > Mobile >  Django - How to manipulate Form data before it gets saved to model?
Django - How to manipulate Form data before it gets saved to model?

Time:01-02

here is my views.py `

def CreateCourseView(request):

    TeeFormSet = inlineformset_factory(Golf_Course, Golf_Tee, form=AddTeeForm, extra=1,)
    if request.method == "POST":
        course_form = AddCourseForm(request.POST)
        teeformset = TeeFormSet(request.POST, instance=course_form.instance)
           
        if course_form.is_valid():
            course_form.save()           
        
        if teeformset.is_valid():
            teeformset.save()

        return redirect("/")
    else:
        course_form = AddCourseForm()
        teeformset = TeeFormSet()
    return render(request, "Courses/add_course_form.html", {'teeformset': teeformset,'course_form': course_form,})

`

here is a shortened view of my models.py

`

class Golf_Tee(models.Model):
    # choice list of index values
    INDEX = [
    (1, 1),
    (2, 2),
    (3, 3),
    (4, 4),
    (5, 5),
    (6, 6),
    (7, 7),
    (8, 8),
    (9, 9),
    (10, 10),
    (11, 11),
    (12, 12),
    (13, 13),
    (14, 14),
    (15, 15),
    (16, 16),
    (17, 17),
    (18, 18),
    ]

    # choice list of par values
    PAR = [
    (3, 3),
    (4, 4),
    (5, 5),
    ]

    course = models.ForeignKey(Golf_Course, on_delete=models.CASCADE)
    tee_name = models.CharField(max_length=255, unique=True)
    course_par = models.IntegerField()
    slope = models.DecimalField(decimal_places=2, max_digits=5)
    rating = models.DecimalField(decimal_places=2, max_digits=5)
    yardage = models.IntegerField()

    hole_1_par = models.IntegerField(choices=PAR, default = PAR[1][1])
    hole_1_yardage = models.IntegerField(default = 0)
    hole_1_index = models.IntegerField(choices=INDEX, default = INDEX[0][0])

    hole_2_par = models.IntegerField(choices=PAR, default = PAR[1][1])
    hole_2_yardage = models.IntegerField(default = 0)
    hole_2_index = models.IntegerField(choices=INDEX, default = INDEX[0][0])

`

I'm trying to not have users enter in the total yardage, when they are already entering yardage for each hole. What I would like to do is, take the values of hole_1_yardage hole_2_yardage, and have the sum of that get used for yardage.

I tried using cleaned_data to get the values, but it didn't seem to save to the model.

CodePudding user response:

You can do the following: using clean. Check the fields hole_1_yardage and hole_2_yardage, if they are not empty, then reset the value of yardage, regardless of the fact that there is already a value there. In this case, the GolfForm form class is created based on the Golf_Tee model. The form class is in the forms.py file:

from django.forms import ModelForm
from django import forms
from .models import student
from django.core.exceptions import ValidationError

class GolfForm(ModelForm):
    class Meta:
        model = Golf_Tee
        fields = '__all__'

    def clean(self):
        cleaned_data = super().clean()
        hole_1_yardage = cleaned_data.get('hole_1_yardage')
        hole_2_yardage = cleaned_data.get('hole_2_yardage')

        if hole_1_yardage!= None and hole_2_yardage!= None:
            cleaned_data['yardage'] = hole_1_yardage   hole_2_yardage

views.py

from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
from .forms import *

class MyFormCreateView(CreateView):
    template_name = 'bboard/tam_form.html'
    form_class = GolfForm
    success_url = reverse_lazy('golf')

bboard in the template path, replace with the name of your application, where your templates are located.

templates

<form method="post">
      {% csrf_token %}
      {{ form.as_p }}
      <input type="submit" value="adding">
</form>

urls.py

from django.urls import path
from .views import *

urlpatterns = [
        path('golf/', MyFormCreateView.as_view(), name='golf'),
    ]
  • Related