在Django中将request.user传递给modelformset_factory()
我的目标是创建一个模型表单集合,其中有一个字段是指向另一个模型的外键。我想根据当前登录的用户来限制外键字段中的下拉选项。
models.py
class WeeklyWinner(models.Model):
league = models.ForeignKey('League')
week = models.IntegerField()
manager = models.ForeignKey('Managers')
class League(models.Model):
league_name = models.CharField(max_length=30)
number_players = models.IntegerField()
league_fee = models.IntegerField()
commissioner = models.ForeignKey(User)
deadline_date = models.DateField(help_text='Date league fees are due')
fine = models.IntegerField(help_text = 'Amount you will charge fantasy managers that pay late', )
draft_date = models.DateField(blank=True, null=True, help_text='Not Required')
transaction_amount = models.IntegerField(help_text='Amount your league will charge for each transaction at the end of the season', )
payment_info = models.TextField(blank=True, help_text='Instruct your league managers on how to pay up. You can place in a paypal link, venmo or tell them to pay you straight cash.')
notes = models.TextField(blank=True, help_text='This information will be included in the email that will be sent to league managers. Provide any extra information on your league that you want them to know.')
number_weeks = models.IntegerField(blank=True, null=True, help_text='Number of weeks your league contains. This is used to determine the number of weekly winners.')
def __unicode__(self):
return self.league_name
class Managers(models.Model):
league = models.ForeignKey('League')
team_name = models.CharField(max_length=30)
first_name_1 = models.CharField(max_length=30)
last_name_1 = models.CharField(max_length=30)
email_1 = models.EmailField()
first_name_2 = models.CharField(max_length=30, null=True, blank=True)
last_name_2 = models.CharField(max_length=30, null=True, blank=True)
email_2 = models.EmailField(null=True, blank=True)
def __unicode__(self):
return self.team_name
forms.py
class WeeklyWinnerForm(ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(WeeklyWinnerForm, self).__init__(*args, **kwargs)
self.fields['manager'].queryset = Managers.objects.filter(league_id = 2)
print self.user
class Meta:
model = WeeklyWinner
fields = ['week', 'manager']
views.py
def weeklywinner(request):
league = get_object_or_404(League, commissioner=request.user)
weeklywinner = WeeklyWinner.objects.filter(league_id=league)
weeklywinnerformset = modelformset_factory(WeeklyWinner, form=WeeklyWinnerForm, max_num=10)
form_data = request.POST if request.method == 'POST' else None
form = weeklywinnerformset(data=form_data)
if form.is_valid():
form.save()
return redirect('/dashboard')
return render(request, 'settings.html', {'form': form})
在我的forms.py中,如果我把league_id设置为一个固定的数字,我能得到我想要的结果。为了实现这个功能,我需要把request.user传递给我的表单或表单集合,但我尝试这样传递用户变量时:
form = weeklywinnerformset(data=form_data, user=request.user)
我遇到了以下错误代码:
Environment:
Request Method: GET
Request URL: http://127.0.0.1:8000/weeklywinner/
Django Version: 1.5.8
Python Version: 2.7.6
Installed Applications:
('django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.sites',
'ledger',
'allauth',
'allauth.account',
'allauth.socialaccount',
'after_response')
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware')
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
113. response = callback(request, *callback_args, **callback_kwargs)
File "/Users/tightflks/Documents/EAV/clients/fantasy/fantasy_development/ledger/views.py" in weeklywinner
379. form = weeklywinnerformset(data=form_data, user=request.user)
File "/Library/Python/2.7/site-packages/django/forms/models.py" in __init__
441. super(BaseModelFormSet, self).__init__(**defaults)
Exception Type: TypeError at /weeklywinner/
Exception Value: __init__() got an unexpected keyword argument 'user'
1 个回答
0
Django内部在创建表单集合时使用了一个叫做modelform_factory的函数,这个函数不会考虑你重写的方法或者自定义的字段。它只会使用你提供的表单类(在你的例子中是“WeeklyWinnerForm”)里的Meta属性,比如字段和排除的字段等。因此,init方法在WeeklyWinnerForm中是不会被调用的。如果你想让它调用,你需要自己实现一个自定义的modelformset_factory。