Имея несколько ForeignKeys в ModelForm
, которые я хочу использовать в мастере форм с modelformset_factory
(не на 100% уверен в наборе форм), мне интересно, как ограничить выбор выпадающего поля, потому что мне нужно делать это динамически. Я хотел попробовать это, написав свою собственную фабрику modelformset, но здесь, в stackoverflow, я читал о других подходах, но, к сожалению, я их не понимаю.
Вот как далеко я пришел:
модели.py
#...
class Attendee(models.Model):
"""Event specific attendee details."""
# event is set by URL.
event = models.ForeignKey(Event)
attendee = models.ForeignKey(Person) # Contact details, should be limited to user
accommodation = models.ForeignKey(Accommodation, blank=True) # *
workshop = models.ForeignKey(Workshop, blank=True) # *
volunteer = models.ForeignKey(Volunteer, blank=True) # *
# *= should be limited to event but I think I will be able to handle that.
#...
class AttendeeForm(forms.ModelForm):
class Meta:
model = Attendee
def __init__(self, *args, **kwargs):
# def __init__(self, user, *args, **kwargs): I tried this but I didn't get
# it to work.
super(AttendeeForm, self).__init__(*args, **kwargs)
# self.fields['attendee'].queryset = Person.objects.filter(owner=user)
self.fields['workshop'].required = True
#...
# This is from https://stackoverflow.com/a/4858044/2704544 but I don't understand it. ##
def form_setup(**kwargs):
def make_form(data, prefix=None, initial=None):
form = (data, prefix, initial)
for k, v in kwargs.items():
if k == 'some_list':
form.fields['some_list'].choices = v # What does that mean?
...
return form
return make_form
#######################################################################################
(ссылка на источник)
просмотры.py
# This is from https://stackoverflow.com/a/623198/2704544 but I don't understand it. ###
class Callback(object):
def __init__(self, field_name, aff):
self._field_name = field_name
self._aff = aff # What is this aff?
def cb(self, field, **kwargs):
nf = field.formfield(**kwargs)
if field.name == self._field_name: # this is 'options' field
nf.queryset = ServiceOption.objects.filter(affiliate=self._aff)
return nf
#######################################################################################
reg_wiz_forms = (
('attendees', modelformset_factory(Attendee, form=AttendeeForm, exclude='event',
# formfield_callback=Callback('option', affiliate).cb Just copied. Why can you call
# cb without arguments?
)),)
class RegWizard(SessionWizardView):
def get_form_instance(self, step):
instance = None
if step == '0':
instance = Attendees.objects.filter(owner__owner=self.request.user)
#...
(ссылка на источник)
urls.py
#...
url(r'^register/$', views.RegWizard.as_view(views.reg_wiz_forms), name='register'),
#...
Я также читал о curry
и других вещах и пытался переопределить get_initkwargs
и другие методы WizardView
, но больше ничего не нашел документ или намеки на эту тему. Может быть, кто-то может мне помочь.
Обновлять
Теперь он частично работает с curry
. Отчасти потому, что он не работает с функцией управления:
просмотры.py
def manage_wizard(request, event):
AttendeeFormSet = modelformset_factory(Attendee, form=AttendeeForm, exclude='event')
AttendeeFormSet.form = staticmethod(curry(AttendeeForm, user=request.user))
wiz = RegWizard
wiz.event = event
return wiz.as_view([('attendees', AttendeeFormSet)])
Я получаю AttributeError: «объект 'function' не имеет атрибута 'base_fields'». Это похоже на ту же проблему здесь.
Но когда я переопределяю WizardView
get_form_list
и вызываю его напрямую в url.py, он работает:
reg_wiz_forms = ('attendees', modelformset_factory(Attendee, form=AttendeeForm, exclude='event'))
class RegWizard(SessionWizardView):
def get_form_list(self):
self.form_list['attendees'].form = staticmethod(curry(AttendeeForm, user=self.request.user))
return super(RegWizard, self).get_form_list()
Теперь мне интересно, есть ли решение без переопределения метода.