Reputation: 21
I have two Models in my application in Django
The Change model is only for storing the change logs made in Model Ip
My models.py
class Change(models.Model):
author = models.ForeignKey('auth.User', null=False, on_delete=models.CASCADE, default='auth.User')
ip = models.ForeignKey('Ip', on_delete=models.CASCADE, default='')
old_cluster = models.ForeignKey('Cluster', on_delete=models.CASCADE, default='')
old_status = models.ForeignKey('Status', on_delete=models.CASCADE, default='')
new_cluster = models.CharField(max_length=20)
new_status =models.CharField(max_length=20)
change_date = models.DateTimeField(default=timezone.now)
class Ip(models.Model):
author = models.ForeignKey('auth.User', null=False, on_delete=models.CASCADE, default='auth.User')
number = models.CharField(max_length=20, unique=True, default='')
status = models.ForeignKey('Status', on_delete=models.CASCADE, default='')
cluster = models.ForeignKey('Cluster', on_delete=models.CASCADE, default='')
created_date = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.number
class Meta:
ordering = ('number',)
my views.py
def ip_edit(request, id):
ip_edit = get_object_or_404(Ip, id=id)
form = EditManagementForm(request.POST, instance=ip_edit)
change_form = ChangeLogsForm()
if request.method == "POST":
if form.is_valid():
ip_edit = form.save(commit=False)
ip_edit.save()
change_form = ChangeLogsForm(request.POST)
if change_form.is_valid():
ip_change = change_form.save(commit=False)
ip_change.author = request.user
ip_change.ip = request.number
ip_change.save()
return redirect('/app/management')
else:
form = EditManagementForm(instance=ip_edit)
args = {
'form': form,
}
return render(request, 'app/ip_edit.html', args
and my forms.py
class EditManagementForm(forms.ModelForm):
class Meta:
model = Ip
fields = (
'number',
'status',
'cluster',
)
widgets = {
'number': TextInput(attrs={'class': 'ls-form-text'}),
}
class ChangeLogsForm(forms.ModelForm):
class Meta:
model = Change
fields = (
'ip',
'old_cluster',
'old_status',
'new_cluster',
'new_status',
)
when I save the ip information editing, no error occurs, but it also does not save the Model Change information
could you help me and let me know if there is any more correct and simple way to store a history of changes in a Model?
Upvotes: 2
Views: 53
Reputation: 1254
Since your Change
model has a foreign key relation to Ip
model and since ip_change
in your view.py presents the instance of Change
model then you should replace ip_change.ip = request.number
with ip_change.ip = ip_edit
because ip_edit
is the instance of Ip
model.
Do you want to perform the save operation on Ip
and Change
models only when both forms are valid? If you want that then this code has one really serious problem which people sometimes overlook and that problem is related to violation of database integrity. Just try to think about the situation when form.is_valid()
returns True
and change_form.is_valid()
returns False
. If that happens you will only save the data into Ip
database table and nothing into Change
database table because this line ip_change.save()
will not be reached. If that happens the data integrity will be ruined and I guess you don't want that - you probably want to ensure that both save
operations either executes or not. You should validate both forms at the same time like if form.is_valid() and change_form.is_valid()
and put the rest of logic into that block.
P.S.
Since I started to talk about the violation of database integrity you should also have a look at atomic database transactions, it can be useful to know.
Upvotes: 2