content: django-form-filters
This data as json
author | category | content | published_date | slug | summary | title | url |
---|---|---|---|---|---|---|---|
ryan | technology | I’ve been working on a Django Project for a while and one of the apps I have tracks candidates. These candidates have dates of a specific type. The models look like this: ## Candidate class Candidate(models.Model): first_name = models.CharField(max_length=128) last_name = models.CharField(max_length=128) resume = models.FileField(storage=PrivateMediaStorage(), blank=True, null=True) cover_leter = models.FileField(storage=PrivateMediaStorage(), blank=True, null=True) email_address = models.EmailField(blank=True, null=True) linkedin = models.URLField(blank=True, null=True) github = models.URLField(blank=True, null=True) rejected = models.BooleanField() position = models.ForeignKey( "positions.Position", on_delete=models.CASCADE, ) hired = models.BooleanField(default=False) ## CandidateDate class CandidateDate(models.Model): candidate = models.ForeignKey( "Candidate", on_delete=models.CASCADE, ) date_type = models.ForeignKey( "CandidateDateType", on_delete=models.CASCADE, ) candidate_date = models.DateField(blank=True, null=True) candidate_date_note = models.TextField(blank=True, null=True) meeting_link = models.URLField(blank=True, null=True) class Meta: ordering = ["candidate", "-candidate_date"] unique_together = ( "candidate", "date_type", ) ## CandidateDateType class CandidateDateType(models.Model): date_type = models.CharField(max_length=24) description = models.CharField(max_length=255, null=True, blank=True) You’ll see from the CandidateDate model that the fields `candidate` and `date_type` are unique. One problem that I’ve been running into is how to help make that an easier thing to see in the form where the dates are entered. The Django built in validation will display an error message if a user were to try and select a `candidate` and `date_type` that already existed, but it felt like this could be done better. I did a fair amount of Googling and had a couple of different _bright_ ideas, but ultimately it came down to a pretty simple implementation of the `exclude` keyword in the ORM The initial `Form` looked like this: class CandidateDateForm(ModelForm): class Meta: model = CandidateDate fields = [ "candidate", "date_type", "candidate_date", "meeting_link", "candidate_date_note", ] widgets = { "candidate": HiddenInput, } I updated it to include a `__init__` method which overrode the options in the drop down. def __init__(self, *args, **kwargs): super(CandidateDateForm, self).__init__(*args, **kwargs) try: candidate = kwargs["initial"]["candidate"] candidate_date_set = CandidateDate.objects.filter(candidate=candidate).values_list("date_type", flat=True) qs = CandidateDateType.objects.exclude(id__in=candidate_date_set) self.fields["date_type"].queryset = qs except KeyError: pass Now, with this method the drop down will only show items which can be selected, not all `CandidateDateType` options. Seems like a better user experience AND I got to learn a bit about the Django ORM | 2021-01-23 | django-form-filters | I’ve been working on a Django Project for a while and one of the apps I have tracks candidates. These candidates have dates of a specific type. The models look like this: ## Candidate class Candidate(models.Model): first_name = models.CharField(max_length=128) last_name = models.CharField(max_length=128) resume = models … | Django form filters | https://www.ryancheley.com/2021/01/23/django-form-filters/ |