Skip to main content

Stack Exchange Network

Stack Exchange network consists of 183 Q&A communities including Stack Overflow, the largest, most trusted online community for developers to learn, share their knowledge, and build their careers.

Visit Stack Exchange
Asked
Modified yesterday
Viewed 90 times
2
\$\begingroup\$

If I can just get a review on my forms for the farrier management system. I greatly appreciate any feedback and let me know if I am following best practices and industry standards.


from django import forms
from django.core.exceptions import ValidationError
from django.contrib.auth.password_validation import validate_password

from .models import User, Client, Job, LineItem, Horse


# User Auth Forms
class RegistrationForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(attrs={
        'id': 'username',
        'name': 'username',
        'class': 'username',
        'placeholder': 'username'
    }))
    email = forms.EmailField(widget=forms.EmailInput(attrs={
        'id': 'email',
        'name': 'email',
        'class': 'email',
        'placeholder': '[email protected]'
    }))
    password = forms.CharField(widget=forms.PasswordInput(attrs={
        'id': 'password',
        'name': 'password',
        'class': 'password',
        'placeholder': 'password'
    }))
    confirmation = forms.CharField(widget=forms.PasswordInput(attrs={
        'id': 'confirmation',
        'name': 'confirmation',
        'class': 'confirmation',
        'placeholder': 'Confirm password'
    }))

    def clean_username(self):
        username = self.cleaned_data.get('username')

        if User.objects.filter(username=username).exists():
            raise forms.ValidationError('Username already taken.')
        
        return username

    def clean_email(self):
        email = self.cleaned_data.get('email')

        if User.objects.filter(email=email).exists():
            raise forms.ValidationError('Email already registered.')
        
        return email

    def clean_password(self):
        password = self.cleaned_data.get('password')

        try:
            validate_password(password)
        except ValidationError as e:
            raise forms.ValidationError(e.messages)

        return password

    def clean(self):
        cleaned_data = super().clean()

        password = cleaned_data.get('password')
        confirmation = cleaned_data.get('confirmation')

        if password != confirmation:
            raise forms.ValidationError('Password and confirmation must match.')
        
        return cleaned_data


class LoginForm(forms.Form):
    username = forms.CharField(widget=forms.TextInput(attrs={
        'id': 'username',
        'name': 'username',
        'class': 'username',
        'placeholder': 'username'
    }))
    password = forms.CharField(widget=forms.PasswordInput(attrs={
        'id': 'password',
        'name': 'password',
        'class': 'password',
        'placeholder': 'password'
    }))


# Model Forms
class ClientForm(forms.ModelForm):
    class Meta:
        model = Client
        fields = '__all__'
        labels = {
            'first_name': 'First Name',
            'last_name': 'Last Name',
            'photo': 'Client Image',
            'business_name': 'Business',
            'phone_number': 'Phone Number',
            'email': 'Email'
        }
        widgets = {
            'first_name': forms.TextInput(attrs={
                'id': 'first-name',
                'name': 'first-name',
                'class': 'first-name'
            }),
            'last_name': forms.TextInput(attrs={
                'id': 'last-name',
                'name': 'last-name',
                'class': 'last-name'
            }),
            'photo': forms.ClearableFileInput(attrs={
                'id': 'client-image',
                'name': 'client-image',
                'class': 'client-image'
            }),
            'business_name': forms.TextInput(attrs={
                'id': 'business',
                'name': 'business',
                'class': 'business',
                'placeholder': 'Business name'
            }),
            'phone_number': forms.TextInput(attrs={
                'id': 'phone-number',
                'name': 'phone-number',
                'class': 'phone-number',
                'type': 'tel',
                'placeholder': '(xxx) xxx-xxxx'
            }),
            'email': forms.EmailInput(attrs={
                'id': 'email',
                'name': 'email',
                'class': 'email',
                'placeholder': '[email protected]'
            })
        }


class JobForm(forms.ModelForm):
    class Meta:
        model = Job
        fields = [
            'date',
            'client',
            'is_paid',
            'next_appointment',
            'comments'
        ]
        labels = {
            'date': 'Date',
            'client': 'Client',
            'is_paid': 'Paid?',
            'next_appointment': 'Next Appt',
            'comments': 'Comments'
        }
        widgets = {
            'date': forms.DateInput(attrs={
                'id': 'job-date',
                'name': 'job-date',
                'class': 'job-date',
                'type': 'date'
            }),
            'client' : forms.Select(attrs={
                'id': 'client',
                'name': 'client',
                'class': 'client',
            }),
            'is_paid': forms.CheckboxInput(attrs={
                'id': 'is-paid',
                'name': 'is-paid',
                'class': 'is-paid'
            }),
            'next_appointment': forms.DateInput(attrs={
                'id': 'next-appt',
                'name': 'next-appt',
                'class': 'next-appt',
                'type': 'date'
            }),
            'comments': forms.Textarea(attrs={
                'id': 'job-comments',
                'name': 'job-comments',
                'placeholder': 'Job comments go here...',
            })
        }
    

class HorseForm(forms.ModelForm):
    class Meta:
        model = Horse
        fields = [
            'name',
            'breed',
            'photo',
            'description'
        ]
        labels = {
            'name': 'Name',
            'breed': 'Breed',
            'photo': 'Horse Image',
            'description': 'Description'
        }
        widgets = {
            'name': forms.TextInput(attrs={
                'id': 'horse-name',
                'name': 'horse-name',
                'class': 'horse-name'
            }),
            'breed': forms.TextInput(attrs={
                'id': 'breed',
                'name': 'breed',
                'class': 'breed',
                'placeholder': 'Thoroughbred'
            }),
            'photo': forms.ClearableFileInput(attrs={
                'id': 'horse-image',
                'name': 'horse-image',
                'class': 'horse-image'
            }),
            'description': forms.Textarea(attrs={
                'id': 'horse-description',
                'name': 'horse-description',
                'placeholder': 'Give a description of the horse...',
            })
        }


class LineItemForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        client = kwargs.pop('client', None)
        super().__init__(*args, **kwargs)

        if client:
            self.fields['horse'].queryset = Horse.objects.filter(owner=client)

    class Meta:
        model = LineItem
        fields = [
            'horse',
            'service',
            'price'
        ]
        labels = {
            'horse': 'Horse',
            'service': 'Service',
            'price': 'Price'
        }
        widgets = {
            'horse' : forms.Select(attrs={
                'id': 'horse',
                'name': 'horse',
                'class': 'horse'
            }),
            'service' : forms.Select(attrs={
                'id': 'service',
                'name': 'service',
                'class': 'service'
            }),
            'price' : forms.NumberInput(attrs={
                'id': 'price',
                'name': 'price',
                'class': 'price'
            }),
        }

New contributor
Joseph Krakos Jr is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$

DRY

I see this:

        widgets = {
            'horse' : forms.Select(attrs={
                'id': 'horse',
                'name': 'horse',
                'class': 'horse'
            }),
            'service' : forms.Select(attrs={
                'id': 'service',
                'name': 'service',
                'class': 'service'
            }),
            'price' : forms.NumberInput(attrs={
                'id': 'price',
                'name': 'price',
                'class': 'price'
            }),
        }

And I really want to write:

        widgets = {
            name: cls(attrs={'id': name, 'name': name, 'class': name})
            for name, cls in (
                ('horse',   forms.Select),
                ('service', forms.Select),
                ('price',   forms.NumberInput)
            )
        }
\$\endgroup\$
1
  • \$\begingroup\$ Other than the fack I could keep things more dry did I do a good job? Is there anything you would consider adding or would do differently? @Chris \$\endgroup\$
    Joseph Krakos Jr
    –  Joseph Krakos Jr
    2026-04-05 21:58:40 +00:00
    Commented 21 hours ago

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Morty Proxy This is a proxified and sanitized view of the page, visit original site.