Updating a Record Creates a new Record

I wish to update a record in Django using a form, but instead it creates a new record. I know it has to do with using get(), but I don’t know how to fix it. Here is the relevant code:

my form:

class  AddRecordForm(forms.ModelForm):

    class Meta:
        model = Model2
        fields = ('field1', 'field2')

my Models:

class Model2(models.Model):

    id = models.CharField(primary_key=True, max_length=12)
    created_at = models.DateTimeField(auto_now_add=True)
    field3 = models.ForeignKey(Model3,  on_delete=models.PROTECT, related_name='master')
    field4 = models.PositiveSmallIntegerField()

    class Meta:
        ordering = ['id']

    def __str__(self):
        return(f"{self.field3} ")
class Model1(models.Model):

    field1 = models.ForeignKey(Model2,  on_delete=models.PROTECT, related_name='list')
    created_at = models.DateTimeField(auto_now_add=True)
    field2 =  models.PositiveSmallIntegerField(null=True, blank=True)

and my view:

def update_record(request, pk):


    record = Model2.objects.get(field2=pk)
    form = AddRecordForm(instance=record)
    if request.method == 'POST':
            form = AddRecordForm(request.POST, instance=record)
        if form.is_valid():
            form.save()
            messages.success(request, "Record updated successfully!")
        return render(request, 'home', {})
        context = {'form':form}
    return render(request, 'update_record.html', context)

Any help would be very much appreciated. Thanks.

I don’t understand your models here. You reference a field2 in Model2, but no such field exists.

You’re right. I mis-transcribed. The form should be:

class  AddRecordForm(forms.ModelForm):

    class Meta:
        model = Model2
        fields = ('field3', 'field4')

Model2 does use a ForeignKey to Model3, but I don’t think Model3 is relevant here. I’ll include that if needed. Thanks.

So how does this correction affect the view?
e.g:

Sorry - yes, the view should be:

def update_record(request, pk):


    record = Model2.objects.get(field4=pk)
    form = AddRecordForm(instance=record)
    if request.method == 'POST':
            form = AddRecordForm(request.POST, instance=record)
        if form.is_valid():
            form.save()
            messages.success(request, "Record updated successfully!")
        return render(request, 'home', {})
        context = {'form':form}
    return render(request, 'update_record.html', context)

First, I cannot recreate the behavior you’re describing here. This leads me to believe there may be more going on here than what you’ve posted.

Where are you getting the pk value from? (What is producing this link that is sending you to this view?)

To try and diagnose this, I’d be checking the data values both in the view before this one in addition to this. I’d either verify with a debugger or through print statements that the id attribute of record is different than the id attribute from the object returned by form.save

I think I made a mess of this post. I apologize. I have revised it. I think I have all of the references correct now, with some missing detail:

Django Record update question:

models:

class Model3(models.Model):

	id = models.CharField(primary_key=True, max_length=10)
	field1 = models.CharField(max_length=80)
	field2 = models.ImageField(null=True, blank=True, upload_to="field2/")
	
	def __str__(self):
		return(f"{self.id} {self.field1}")
	
	class Meta:
		ordering = ['id']

class Model2(models.Model):

	id = models.CharField(primary_key=True, max_length=12)
	created_at = models.DateTimeField(auto_now_add=True)
	field3 = models.ForeignKey(Model3,  on_delete=models.PROTECT, related_name='Model3')
	field4 = models.PositiveSmallIntegerField()

	class Meta:
		ordering = ['id']
		

	def __str__(self):
		return(f"{self.field3} {self.field4}")


class Model1(models.Model):

	field5 = models.ForeignKey(Model2,  on_delete=models.PROTECT, related_name='cardrecords')
	created_at = models.DateTimeField(auto_now_add=True)
	field6 = models.PositiveIntegerField()
	field7 =  models.PositiveSmallIntegerField(null=True, blank=True)
	
	class Meta:
		ordering = ['field5']
		indexes = [
        	models.Index(fields=['field5']),
        	
		]

	def __str__(self):
		return(f"{self.field5} {self.field5.field4} {self.field5.name}")

Form:

class  Form2(forms.ModelForm):

	class Meta:
		model = Model1
		fields = ('field5', 'field7', )

Views:

def record_list2(request):

	subrecords = Model1.objects.all().order_by('field5')
	masterrecords = Model2.objects.all()
	
	return render(request, 'record_list2.html', {'subrecords':subrecords}, {'masterrecords':masterrecords})


def singlerecord(request, pk):
	
	
		ind_record = Model1.objects.get(product_id=pk)
	
		return render(request, 'SingleRecord.html', {'ind_record':ind_record})


def update_record2(request, pk):

	
		record = Model1.objects.get(field6=pk)
		records = Model1.objects.all()
		form = Form2(instance=record)
		
		if request.method == 'POST':
			form = Form2(request.POST, instance=record)
			if form.is_valid():
				form.save()
				
				messages.success(request, "Record updated successfully!")
				return render(request, 'record_list2.html', {'records':records})
		context = {'form':form}

		return render(request, 'update_record2.html', context)

SingleRecord.html:

<a class="btn btn-secondary btn-lg" href="{% url 'update_record2' ind_record.field6 %}" role="button">Update Record</a>

recordlist2.html

{% for subrecord in subrecords %}
	<tr>
	<td>{{ subrecord.field5 }}</td>

	 <td><a href="{% url 'singlerecord' subrecord.field6 %}">{{ subrecord.field6 }}</td>
	</tr>
{% endfor %}

In response to your last answer, for sure it makes a new record in Model1 when it performs the save(). I’m not sure where to put the print statements, so I’m not sure how to check it.

We might be close enough I think.

However, there’s still this line in the singlerecord view that I need to question:

    ind_record = Model1.objects.get(product_id=pk)
                                    ^^^^^^^^^^

Model1 doesn’t have a product_id field that you have identified. Is this supposed to be field5_id? If so, then I don’t see how this aligns with the reference generated by record_list2.

As far as print statements for debugging this, I’d print the instances of Model1 being retrieved as ind_record in singlerecord, and record in update_record2, and then change the form.save() to something like new_model1 = form.save(), and then print new_model1.
I also wouldn’t just print(ind_record), etc. I’d print all the fields.

Ah, I missed that one. product_id=pk should be field6=pk.

I’ll work on your suggestion. Thanks.

Ok - I got it. I feel foolish. My update button was pointing to my add_record url, and not my update_record url. I should have looked at the terminal output sooner - I might have noticed and saved you all of the trouble. Thanks for the help once again!