我正在制作一个选举信息应用程序,我希望允许当前登录的用户能够宣布自己并且仅自己作为选举中的候选人。
我正在使用Django的内置ModelForm和CreateView。我的问题是Run for Office表单(换句话说,'创建候选人'表单)允许用户选择数据库中的任何用户来制作候选人。
我希望Run for Office中的用户字段自动设置为当前登录的用户,并且要隐藏此值,因此登录用户无法将该字段的值更改为其他人。
views.py
class CandidateCreateView(CreateView):
model = Candidate
form_class = CandidateForm
template_name = 'candidate_create.html'
def form_valid(self, form):
f = form.save(commit=False)
f.save()
return super(CandidateCreateView, self).form_valid(form)
forms.py
class CandidateForm(forms.ModelForm):
class Meta:
model = Candidate
models.py
class Candidate(models.Model):
user = models.ForeignKey(UserProfile)
office = models.ForeignKey(Office)
election = models.ForeignKey(Election)
description = models.TextField()
def __unicode__(self):
return unicode(self.user)
def get_absolute_url(self):
return reverse('candidate_detail', kwargs={'pk': str(self.id)})
答案 0 :(得分:39)
从呈现的表单中删除用户字段(使用exclude
或fields
,https://docs.djangoproject.com/en/dev/topics/forms/modelforms/#selecting-the-fields-to-use)
class CandidateForm(forms.ModelForm):
class Meta:
model = Candidate
exclude = ["user"]
在创建视图中查找用户个人资料并设置用户字段。
class CandidateCreateView(CreateView):
...
def form_valid(self, form):
candidate = form.save(commit=False)
candidate.user = UserProfile.objects.get(user=self.request.user) # use your own profile here
candidate.save()
return HttpResponseRedirect(self.get_success_url())
答案 1 :(得分:2)
我们不想设置null=True
,因为我们不想在模型和/或数据库级别允许null
用户
我们不想设置blank=True
来破坏模型的可读性,因为用户实际上不会空白
@ nbm.ten 解决方案是一个很好的解决方案。与使用nbm中的 model 设置用户(例如this one)的该问题相比,该解决方案的其他解决方案具有优势。ten不会破坏上述假设。我们不想弄乱模型来解决问题!
但是在这里,我基于django文档(Models and request.user)添加了另外两个解决方案:
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView
from myapp.models import Candidate
class CandidateCreate(LoginRequiredMixin, CreateView):
model = Candidate
exclude = ['user']
def form_valid(self, form):
form.instance.user = self.request.user
return super().form_valid(form)
class CandidateForm(ModelForm):
class Meta:
model = Candidate
exclude = [ 'user',]
class CandidateAddView(LoginRequiredMixin, View):
def get(self, request, *args, **kwargs):
form = CandidateForm()
context = {'form':form}
return render(request, 'myapp/addcandidateview.html', context)
def post(self, request, *args, **kwargs):
form = CandidateForm(request.POST)
form.instance.user = request.user
if form.is_valid():
form.save()
return redirect(reverse('myapp:index'))
请注意, LoginRequiredMixin
会阻止未登录的用户访问表单。如果我们忽略了这一点,则需要处理form_valid()
或post()
中的未授权用户。
还exclude = ['user']
阻止用户字段显示在表单上。
我们使用form.instance.user
将用户设置为form.data
或form.cleaned_data
无效的用户