0

I have model

class Listings(models.Model):
    user_id = models.ForeignKey(
        User,
        on_delete=models.CASCADE
    )
    title = models.CharField(max_length=180)
    desc = models.CharField(max_length=900)
    price = models.IntegerField(validators=[MinValueValidator(1)])
    img = models.ImageField(upload_to='uploads')
    timestamp = models.DateTimeField(auto_now_add=True)

And form class

class ListingForm(ModelForm):
    class Meta:
        model = Listings
        fields = ('title', 'category', 'price', 'desc', 'img')
        labels = {
            'desc': 'Description',
            'img': 'Upload photo',
            'price': 'Starting price'
        }

I want to add HTML attributes like min="0" or remove required from my img = models.ImageField(upload_to='uploads') for example. How can I implement this?

I found in stack overflow method with widgets = {'price': IntegerField(attrs='min': 0}) and I also tried ...forms.IntegerField... but I had

TypeError: __init__() got an unexpected keyword argument 'attrs'

And I also found solution with

def __init__(self, *args, **kwargs):
    super(Listings, self).__init__(*args, **kwargs)
    self.fields['price'].widget.attrs.update({
        'min': 1
    })

(I added it to my form class)

But also did not work

super(Listings, self).__init__(*args, **kwargs)
TypeError: super(type, obj): obj must be an instance or subtype of type
[05/Jan/2023 19:22:01] "GET /create_listing HTTP/1.1" 500 60691
0

2 Answers 2

1

An IntegerField [Django-doc] is not a widget, but a form field. The default widget for an IntegerField is a NumberInput [Django-doc]:

class ListingForm(ModelForm):
    class Meta:
        model = Listings
        fields = ('title', 'category', 'price', 'desc', 'img')
        labels = {
            'desc': 'Description',
            'img': 'Upload photo',
            'price': 'Starting price',
        }
        widget = {'price': forms.NumberInput(attrs={'min': 0})}

or you can work with:

class ListingForm(ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['price'].widget.attrs['min'] = 1

    class Meta:
        model = Listings
        fields = ('title', 'category', 'price', 'desc', 'img')
        labels = {
            'desc': 'Description',
            'img': 'Upload photo',
            'price': 'Starting price',
        }
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, I already found the solution by myself. widget=forms.NumberInput really was the solution
0

In case it will be useful for someone. You should place (in my case)

class ListingForm(ModelForm):
    price = forms.IntegerField(widget=forms.NumberInput(
        attrs={
            'min': 0
        }))
    desc = forms.CharField(widget=forms.Textarea(
        attrs={
            'placeholder': 'Enter your description',
        }))
    img = forms.ImageField(widget=forms.FileInput(
        attrs={
            'id': 'img'
        }
    ))
    class Meta:
    # and code from question

And if you need to remove required from any field, you can add

    <script>
        document.getElementById("img").required = false;
    </script>

To your html file

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.