In the form's __init__ method, you'll have to modify the queryset of the field.
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['choretime'].queryset |= ChoiceTime.objects.filter(pk=self.instance.pk)
I hope that helps!
From: django-users@googlegroups.com [mailto:django-users@googlegroups.com] On Behalf Of Jim Illback
Sent: Friday, April 27, 2018 11:16 AM
To: Django users
Subject: Re: Dynamically altering a (ForeignKey) ModelChoiceField's values
To make this easier, here is just a simple the question.
Does Django give a method that can be overridden while processing a form which has access to the incoming URL parameters and precedes the display of the form's fields, specifically being able to alter the fields's query set before it is displayed?
Thanks for any help to answer this question.
Jim Illback
On Apr 25, 2018, at 10:41 AM, Jim Illback <subaru_87@hotmail.com> wrote:
I wondered if anyone has had to alter the queryset behind a model form's foreign key field which presents as a model choice field?
Briefly, I have a client attribute table with the foreign key to a chore/time table. For an add of the client attribute table, I want to limit entries to unassigned chore/time combinations only. This works perfectly during my CreateView. Here are some extracts to show specifics:
Models.py:
class ChoreTime(models.Model):
chore = models.ForeignKey(Chore, on_delete=models.CASCADE)
time = models.ForeignKey(TimePeriod, on_delete=models.CASCADE)
priority = models.BooleanField(default=False)
…
class Checkin(models.Model):
client = models.ForeignKey(Client, on_delete=models.CASCADE)
choretime = models.ForeignKey(ChoreTime, on_delete=models.CASCADE)
…
Forms.py:
class CheckinForm(forms.ModelForm):
assigned_qs = Checkin.objects.values('choretime').filter(choretime_id__isnull=False)
choretime = forms.ModelChoiceField(queryset=ChoreTime.objects.exclude(pk__in=assigned_qs))
…
However, I cannot get the any design to work on an UpdateView form. Using the same form as above, the current value does not even show up – it is blank – because, of course, that entry is already assigned so is excluded.
What I'd like is to have the above exclusions BUT be able to also add in the single entry assigned to the client being updated – so the entry will show that specific assignment (as well as limiting any possible change options to unassigned values - just like on the Create).
The problems with various approaches I've tried are:
1. Anything done before the form is fully assembled won't have the existing form's Checkin ID value (which is part of the URL, just BTW). This is needed to look up and add the existing entry. So, having a database view won't work without being able to communicate the existing person's assignment ID to the view. Similarly, using an override queryset on the form, like done above for the Create, needs that ID, too.
2. If I do the queries in the class's GET method routine as ORM objects, I must use UNION (a union of the exclusions as above plus the existing update client's assignment). That union option keeps giving an error that one of the ORM querysets is not a queryset. However, they are both using "<class>.objects.filter…". It seems like complex queries don't work with the union command. If I use raw SQL, the query works but the assignment to the choretime field's queryset fails.
Does anyone have experience with this sort of behavior and be willing to give guidance?
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/F0B95720-C669-4CE5-912E-5167E3B89DFE%40hotmail.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users+unsubscribe@googlegroups.com.
To post to this group, send email to django-users@googlegroups.com.
Visit this group at https://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/C42DA3B1-C882-4889-995B-49580840F539%40hotmail.com.
For more options, visit https://groups.google.com/d/optout.
No comments:
Post a Comment