我是Django的新手,这个问题可能很简单,但它已经困扰了我一段时间了。
<form method="post" action="/vote/" class="vote_form">
<input type="hidden" id="id_link" name="user_profile" class="hidden_id" value="5" />
<input type="hidden" id="id_voter" name="voter" class="hidden_id" value="3" />
New Score: <input name="score" class="" value="7" />
<button type="submit">Submit</button>
</form>
urls.py
url(r'^vote/$', auth(VoteFormView.as_view()), name="vote"),
views.py
class VoteFormView(FormView):
form_class = VoteForm
def create_response(self, vdict=dict(), valid_form=True):
response = HttpResponse(json.dumps(vdict))
response.status = 200 if valid_form else 500
return response
def form_valid(self, form):
profile = get_object_or_404(UserProfile, pk=form.data['user_profile'])
user = self.request.user
score = form.cleaned_data['score']
prev_votes = Vote.objects.filter(voter=user, profile=profile)
has_voted = (len(prev_votes) > 0)
ret = {"success": 1, "profile": profile, "voter: ": user}
if not has_voted:
# add vote
v = Vote.objects.create(voter=user, profile=profile, score=score)
ret["voteobj"] = v.id
# else response already ranked
return self.create_response(ret, True)
def form_invalid(self, form):
...do something when form invalid...
forms.py
class VoteForm(forms.ModelForm):
class Meta:
model = Vote
models.py
class Vote(models.Model):
voter = models.ForeignKey(User)
profile = models.ForeignKey(UserProfile)
score = models.FloatField(default=10.0)
def __unicode__(self):
return "%s voted %s" % (self.voter.username, self.profile)
class UserProfile(models.Model):
user = models.OneToOneField(User, unique=True)
# Extra attributes
如您所见,我有一个包含2个字段的简单表单:user_profile(用户个人资料的PK)和分数。提交表单后,出现此错误:"form_errors": {"profile": ["This field is required."]}
。所以总是去form_invalid
。
如果不是form_valid,我应该在哪里获取配置文件对象?
我尝试重新定义下面的VoteForm,这也不起作用。
class VoteForm(forms.ModelForm):
def clean_profile(self):
profile_pk = self.cleaned_data['profile']
profile = None
try:
profile = UserProfile.objects.get(pk=profile_pk)
except UserProfile.DoesNotExist:
raise forms.ValidationError("User profile doesn't exist.")
return profile
def save(self, *args, **kwargs):
vote = super(VoteForm, self).save(*args, **kwargs)
return vote
class Meta:
model = Vote
有什么想法吗?
答案 0 :(得分:0)
隐藏字段的名称为user_profile
,但您的代码仅将其称为profile
。尝试更改表单的html,使其名为profile
。
另外,您应该在表单中包含选民ID,该ID应根据登录用户添加到您的处理代码中。目前,任何人都可以更改选民隐藏字段并为其他用户录制投票。
答案 1 :(得分:0)
您必须将隐藏的输入名称从user_profile更改为个人资料。
请记住,这是一个糟糕的设计,因为任何人都可以注入任意的选民ID。
我将如何做到这一点
class VoteForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
super(VoteForm, self).__init__(*args, **kwargs)
def save(self, *args, **kwargs):
# manipulate self.user
然后在你的视图中
form = VoteForm(..., user=request.user)