Eduardo Correia
Eduardo Correia

Reputation: 21

inserting data in two database at the same time

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

Answers (1)

T.Tokic
T.Tokic

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 saveoperations 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

Related Questions