我一直试图在DetailView中构建一个验证表单,该表单将参数与标志键进行比较,如果正确,它将更新另一个模型中的某些字段(得分字段)。 该视图存在于Django应用程序中(“挑战”),并提供给定应用程序中的模型。但是,我想从另一个模型更改两个字段。 另一个模型存在于另一个应用程序中(“帐户”。 但是,我无法从第二个模型中选择所需的字段。我收到
的ObjectDoesNotExist异常u= User.objects.get(pk=self.request.user.pk
无论我知道它在那里。
令人不安的课程
class ChallengeDetailView(FormMixin,DetailView):
model = Challenge
form_class = FlagForm
def get_success_url(self):
return reverse('challenges:challenge_detail', kwargs={'pk': self.object.pk})
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['form'] = self.get_form()
return context
def post(self, request, *args, **kwargs):
if not request.user.is_authenticated:
return HttpResponseForbidden()
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
def form_valid(self, form):
f=form.cleaned_data['flag']
if f==self.object.flag:
try:
u= User.objects.get(pk=self.request.user.pk)
ch=Challenge.objects.get(flag=f)
request.user.score+=ch.point
except ObjectDoesNotExist as e:
pass
return super().form_valid(form)
也许模型和FlagForm一样也有帮助:
class FlagForm(forms.Form):
flag = forms.CharField()
用户模型:
class User(auth.models.User, auth.models.PermissionsMixin):
score = models.IntegerField(default=0)
def __str__(self):
return self.username
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
挑战模型:
class Challenge(models.Model):
title = models.CharField(max_length=200)
text = models.TextField()
url = models.URLField(max_length=200,null=False)
created_date = models.DateTimeField(default=timezone.now)
points = models.IntegerField(default=0)
flag = models.CharField(max_length=100)
def get_absolute_url(self):
return reverse("challenges:challenge_detail",kwargs={'pk':self.pk})
def __str__(self):
return self.title
我也尝试过通过self.request.user.score
与User模型进行交互,但是它说没有这样的字段。
我真的很感谢您的帮助!
答案 0 :(得分:2)
尝试以下检查清单。希望对您有帮助。
# ....
AUTH_USER_MODEL = 'myapp.User'
# ....
class User(auth.models.AbstractUser):
score = models.IntegerField(default=0)
def __str__(self):
return self.username
def form_valid(self, form):
f=form.cleaned_data['flag']
if f == self.object.flag:
ch = Challenge.objects.get(flag=f)
self.request.user.score += ch.point
self.request.user.save()
return super().form_valid(form)
答案 1 :(得分:0)
对于所有模型来说,ObjectDoesNotExist
例外是一个包罗万象的东西,我通常更倾向于更具体一些,并使用<Model Name>.DoesNotExist
。为什么这有关系?对于该代码段,遗漏的User
或Challenge
引发了异常,这并不明显。
看起来您的视图需要一个已登录的用户,但是从您发布的代码来看,它似乎没有强制执行。也许您以匿名用户身份访问记录的视图?您可以将LoginRequiredMixin
添加到视图中,以确保不是这种情况。如果这样做,request.user
将不是您的用户实例,它将是Django's AnonymousUser
的实例。
您不需要像这样来获取用户:u= User.objects.get(pk=self.request.user.pk)
,您可以像这样u = self.request.user
来直接获取它,然后在更新配置文件request.user.score+=ch.point
时,不要别忘了通过调用user.save()
保存它。
将所有内容放在一起,我认为您应该能够按如下所示重写try块中的行:
u = self.request.user
ch = Challenge.objects.get(flag=f)
u.score += ch.point
u.save()
如果问题仍然存在,请删除try / catch以传播原始异常,然后将引用添加到您的帖子中,如果没有它,很难为您提供更多帮助。