I am a beginning programmer in Django/Python and I am now looking for a way to robustly create and update my models. I would expect this is a very common problem. Some example code of how to do this the right way would be very much appreciated.
Problems which I struggling with is that I am not sure where to put the save() command. Now there are multiple places where I put the save() method. And sometimes I have to multiple times hit the save button on the various views before a change on a low level trickless up to a higher level model.
In this example I use two simplified models named Medium and Circuit. The create methods for the two models are specified as well as a set_medium and set_circuit method, this shows how I am currently doing it.
class Circuit(models.Model):
medium = models.ForeignKey('medium.Medium', related_name='medium_related', on_delete=models.CASCADE)
temperature = models.FloatField(default=60, help_text='[degC]')
glycol_percentage = models.FloatField(default=0, choices = choices.GLYCOL_PERCENTAGE)
@classmethod
def create( cls,
temperature,
glycol_percentage):
circuit = cls( temperature = temperature,
glycol_percentage = glycol_percentage)
circuit.medium = Medium.create(circuit.temperature, circuit.glycol_percentage)
circuit = circuit.set_circuit(circuit)
circuit.save()
return circuit
def set_circuit(self, circuit):
circuit.medium.glycol_percentage = circuit.glycol_percentage
circuit.medium.temperature = circuit.temperature
circuit.medium = circuit.medium.set_medium(circuit.medium)
return circuit
class Medium(models.Model):
glycol_percentage = models.FloatField(default=0, choices = choices.GLYCOL_PERCENTAGE)
temperature = models.FloatField(default=60, help_text='[degC]')
# Calculated properties
rho = models.FloatField(default=1000, help_text='[kg/m3]')
@classmethod
def create( cls, temperature, glycol_percentage):
medium = cls( temperature = temperature,
glycol_percentage = glycol_percentage)
medium = medium.set_medium(medium)
medium.save()
return medium
def set_medium(self, medium):
medium.rho = services.rho(temperature=medium.temperature, glycol_percentage=medium.glycol_percentage)
return medium
Below is how I typically write my Create and Update views.
class CircuitCreateView(LoginRequiredMixin, CreateView):
model = Circuit
template_name = 'circuit/create.html'
form_class = CircuitForm
def form_valid(self, form):
circuit = Circuit.create( glycol_percentage = form.cleaned_data['glycol_percentage'],
temperature = form.cleaned_data['temperature'])
circuit.save()
return HttpResponseRedirect(reverse('circuit:detail', args=(circuit.id,)))
class CircuitUpdateView(LoginRequiredMixin, UpdateView):
model = Circuit
template_name = 'circuit/detail-update.html'
form_class = CircuitForm
def form_valid(self, form):
circuit = get_object_or_404(Circuit, pk=self.kwargs['pk_circuit'])
circuit.glycol_percentage = form.cleaned_data['glycol_percentage']
circuit.temperature = form.cleaned_data['temperature']
circuit = circuit.set_circuit(circuit)
circuit.save()
return HttpResponseRedirect(reverse('circuit:detail', args=(circuit.id,)))