How to show read only unique id in form?

Viewed 154

I currently have a model that is called services, shown here...

class Services(models.Model):

    service_sku = models.AutoField(primary_key=True)
    name = models.CharField(max_length=200, null=True)
    price = models.FloatField(null=True)

forms.py

class ServiceForm(forms.ModelForm):

    class Meta:
        model = Services
        fields = '__all__'

Based on the code shown above, I have two views, one will create instances of the model above and the other view will update the instance, as follows

def NewServices(request):
    form = ServiceForm()
    if request.method == 'POST':
        form = ServiceForm(request.POST or None)
        if form.is_valid():
            form.save()
            return redirect('/')
    return render(request, 'accounts/new_services.html', {'form': form})


def EditServices(request,pk):


    service = Services.objects.get(service_sku=pk)
    form = ServiceForm(instance=service)
    if request.method == 'POST':
        form = ServiceForm(request.POST, instance=service)
        if form.is_valid():
            form.save()
            return redirect('/')

    context = {'form':form}
    return render(request, 'accounts/edit_services.html',context)

Template as follows

<div class="row">
    <div class="col-md-7">
        <div class="card card-body">
            <form action="" method="POST">
                {% csrf_token %}
                {{form}}
                <hr>
                <input type="submit" name="Update">
            </form>
        </div>
    </div>
</div>

Is it possible to show a readyonly of the service_sku within in my template form, when a instance needs to be updated and when a service_sku readonly is shown to be autogenerated in a template when creating a instance?

1 Answers

Yes. You can include the field in a form, so likely you should make a separate one to update:

class ServiceEditForm(forms.ModelForm):
    service_sku = forms.IntegerField(disabled=True)

    class Meta:
        model = Services
        fields = ('service_sku', 'name', 'price')

In the form you then simply use that new form:

def EditServices(request,pk):
    service = Services.objects.get(service_sku=pk)
    if request.method == 'POST':
        form = ServiceEditForm(request.POST, request.FILES, instance=service)
        if form.is_valid():
            form.save()
            return redirect('/')
    else:
        form = ServiceEditForm(instance=service)
    context = {'form':form}
    return render(request, 'accounts/edit_services.html', context)

Using disabled=True [Django-doc] does not only make sure the field is disabled at the client side, but it will also prevent a person to make a malicious POST request.

Related