Django adding data form multiple forms of one model to database

1.7k Views Asked by At

I have one model Measurement, two forms MeassurementSystolicPressureForm and MeassurementDiastolicPressureForm. I want to make a view that allows user to add both of them to the database. Each has fields: username, measurement_date, value, measurement_type. When I fill forms on my webpage two records are added to the db, each has a good username and measurement_type, but measurement_date and value are the same for both records. Can you help me spotting what I'm doing wrong?

Here is my code:

models.py

class Measurement(models.Model):
    value = models.IntegerField()
    measurement_type = models.CharField(max_length=6, default='measurement', blank=True)
    username = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    measurement_date = models.DateTimeField(default=datetime.now, editable=True)

forms.py

class MeassurementSystolicPressureForm(ModelForm):
    class Meta:
        model = Measurement
        fields = ['value',  'measurement_date']


class MeassurementDiastolicPressureForm(ModelForm):
    class Meta:
        model = Measurement
        fields = ['value', 'measurement_date']

views.py

def new_measurement(request):
    if request.method == 'POST':
        form_SP = MeassurementSystolicPressureForm(request.POST or None)
        form_DP = MeassurementDiastolicPressureForm(request.POST or None)
        if form_CS.is_valid() or form_CR.is_valid():

            temp_S = form_SP.save(commit=False)
            temp_S.username = request.user
            temp_S.measurement_type = 'syspres'
            temp_S.save()

            temp_D = form_DP.save(commit=False)
            temp_D.username = request.user
            temp_D.measurement_type = 'diapres'
            temp_D.save()

            return redirect('/')
    else:
        form_SP = MeassurementSystolicPressureForm()
        form_DP = MeassurementDiastolicPressureForm()
        args = {'form_SP': form_SP, 'form_DP': form_DP}
        return render(request, 'measurements.html', args)

If for example I submit data for:

Systolic Pressure:
value: 120 
date: 2019-01-15 16:15:32
Diastolic Pressure:
value: 80
date: 2019-01-15 15:00:00`

In my database I have two records:

username: Julka, measurement_type: 
syspres, value: 80, date: 2019-01-15 15:00:00
username: Julka, measurement_type: diapres, value: 80, date: 2019-01-15 15:00:00

I have no idea what to do.

2

There are 2 best solutions below

0
Vladimir Goncharuk On

In an HttpRequest object, the GET and POST attributes are instances of django.http.QueryDict. This type alone cannot determine which form was submitted. Your forms have the same fields, so then one form is valid, other form valid too. That's why you have measurement_date and value are the same for both records. To solve this problem, you can add additional hidden fields to your forms and look at them from which form was sent. Some like this:

class MeassurementSystolicPressureForm(ModelForm):
    flag_Systolic = forms.IntegerField()
    class Meta:
        model = Measurement
        fields = ['value',  'measurement_date']
    def __init__(self, *args, **kwargs):
        super(MeassurementSystolicPressureForm, self).__init__(*args, **kwargs)
        self.fields['flag_Systolic'].widget = forms.HiddenInput()


class MeassurementDiastolicPressureForm(ModelForm):
    flag_Diastolic = forms.IntegerField()
    class Meta:
        model = Measurement
        fields = ['value', 'measurement_date']
    def __init__(self, *args, **kwargs):
        super(MeassurementDiastolicPressureForm, self).__init__(*args, **kwargs)
        self.fields['flag_Diastolic'].widget = forms.HiddenInput()

and in your views:

def new_measurement(request):
    if request.method == 'POST':
        if 'flag_Systolic' in request.POST:
            form_SP = MeassurementSystolicPressureForm(request.POST)
            if form_SP.is_valid():
                temp_S = form_SP.save(commit=False)
                temp_S.username = request.user
                temp_S.measurement_type = 'syspres'
                temp_S.save()
                return redirect('/')
        elif 'flag_Diastolic' in request.POST:
            form_DP = MeassurementDiastolicPressureForm(request.POST)
            if form_DP.is_valid():
                temp_D = form_DP.save(commit=False)
                temp_D.username = request.user
                temp_D.measurement_type = 'diapres'
                temp_D.save()
                return redirect('/')
    else:
        form_SP = MeassurementSystolicPressureForm()
        form_DP = MeassurementDiastolicPressureForm()
        args = {'form_SP': form_SP, 'form_DP': form_DP}
        return render(request, 'measurements.html', args)
0
Yacine On

I know maybe it is too late but it might be helpful for other people facing the same problem.

One easier solution would be creating the object in the View and passing it to both forms:

from .models import Measurement
def new_measurement(request):
    user=request.user                       #the authenticated user
    if request.method == 'POST':
        measurement=Measurement(username=user)
        form_SP = MeassurementSystolicPressureForm(request.POST or None, instance=measurement)
        form_DP = MeassurementDiastolicPressureForm(request.POST or None, instance=measurement)
        if form_CS.is_valid() or form_CR.is_valid():
            form_CS.save()
            form_CR.save()
            return redirect('/')
    else:
        form_SP = MeassurementSystolicPressureForm()
        form_DP = MeassurementDiastolicPressureForm()
        args = {'form_SP': form_SP, 'form_DP': form_DP}
        return render(request, 'measurements.html', args)