Home > Software design >  Django admin list : how to specify custom field instead of model __str__ method?
Django admin list : how to specify custom field instead of model __str__ method?

Time:08-17

I have a model that has multi attributes rendered in __str__ method. I only want to display the name attribute in the admin list display. How do I achieve this without overriding __str__? In the example below I have tried using list_display in the admin model but Django still renders the attributes in __str__ defined for the model.

models.py:

class Product(models.Model):
    """
    Product
    """

    id = models.PositiveBigIntegerField(primary_key=True)
    attributes = models.JSONField()
    labels = models.JSONField()
    name = models.TextField()
    relative_url = models.TextField()
    image = models.URLField()
    delivery = models.TextField()
    online = models.BooleanField()
    is_customizable = models.BooleanField()
    is_exclusive = models.BooleanField()
    url = models.TextField()
    max_price = models.PositiveIntegerField()
    min_price = models.PositiveIntegerField()
    currency = models.ForeignKey(Currency, on_delete=models.CASCADE)
    discount_percentage = models.PositiveSmallIntegerField(default=0)
    recommended_retail_price = models.PositiveIntegerField()

    def __str__(self) -> str:
        product_str = (
            f"id: {self.id}\n"
            f"attributes: {self.attributes}\n"
            f"labels: {self.labels}\n"
            f"name: {self.name}\n"
            f"relative_url: {self.relative_url}\n"
            f"image: {self.image}\n"
            f"delivery: {self.delivery}\n"
            f"online: {self.online}\n"
            f"is_customizable: {self.is_customizable}\n"
            f"is_exclusive: {self.is_exclusive}\n"
            f"url: {self.url}\n"
            f"max_price: {self.max_price}\n"
            f"min_price: {self.min_price}\n"
            f"currency: {self.currency}\n"
            f"discount_percentage: {self.discount_percentage}\n"
            f"recommended_retail_price: {self.recommended_retail_price}\n"
        )

        return product_str

    def get_absolute_url(self) -> str:
        return reverse("web:product-detail", args=[self.id])

    class Meta:
        db_table = "product"
        ordering = ["recommended_retail_price"]

admin.py:

class ProductAdmin(admin.ModelAdmin):
    list_display = ("name",)
    form = ProductForm

forms.py:

class ProductForm(forms.ModelForm):
    class Meta:
        model = Product
        fields = "__all__"

CodePudding user response:

You can also customize your model admin display using below way:

class ProductAdmin(admin.ModelAdmin):
    list_display = ("get_name",)
    form = ProductForm

    def get_name(self, obj):
        return obj.name  # here you can do whatever you want

CodePudding user response:

Solved it. I was using the default admin forms for the models and not explictly registering my admin forms. I updated my admin.py to explictly register my admin models, e.g.:

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ("id", "name", "recommended_retail_price", "currency")
    list_per_page = 10
    form = ProductForm
  • Related