'How can a field in the Django admin panel be made writable for a model only when it is being created, and it'll be read only at other times?

I am working on a project similar to a stock market. In this project I have a model called Stock which is as follows:

class Stock(models.Model):
    _title = models.CharField(max_length=50)
    _description = models.TextField()
    _total_subs = models.IntegerField()
    _sold_out_subs = models.IntegerField()
    _created_at = models.DateTimeField(auto_now_add=True)
    _updated_at = models.DateTimeField(auto_now=True)
    _status = models.BooleanField()

Access to create new records for this model is to be supposed only through the Django admin panel, so in the admin.py file in my app I wrote a class to manage it called StockAdmin as follows:

class StockAdmin(admin.ModelAdmin):
    list_display = []
    readonly_fields = ['_sold_out_subs']
    
    class Meta:
        model = Stock

How can I make a _total_subs so that it can be writable when it being create and then it should be in read-only fields?



Solution 1:[1]

you can get readonly fields based on object like this

class StockAdmin(admin.ModelAdmin):
    list_display = []

    def get_readonly_fields(self, request, obj=None):
       if obj:
           return ['_sold_out_subs']
       else:
           return []

besides that its not good django practice to start field names with underscore since they imply that the field is a private. check this answer for more info What is the meaning of single and double underscore before an object name?

Solution 2:[2]

By adding list_editable = [] add all fields you have except _total_subs

Solution 3:[3]

Use get_readonly_fields method

class StockAdmin(admin.ModelAdmin):
    def get_readonly_fields(self, request, obj=None):
        return ['_sold_out_subs'] if obj else []

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jameel Hamdan
Solution 2 Mohamed Hamza
Solution 3 Javad Nikbakht