Django无法从DetailView更新其他模型

时间:2019-02-04 12:01:43

标签: django

我一直试图在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模型进行交互,但是它说没有这样的字段。 我真的很感谢您的帮助!

2 个答案:

答案 0 :(得分:2)

尝试以下检查清单。希望对您有帮助。

settings.py

# ....
AUTH_USER_MODEL = 'myapp.User'
# ....

models.py

class User(auth.models.AbstractUser):
    score = models.IntegerField(default=0)

    def __str__(self):
        return self.username

views.py

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。为什么这有关系?对于该代码段,遗漏的UserChallenge引发了异常,这并不明显。

看起来您的视图需要一个已登录的用户,但是从您发布的代码来看,它似乎没有强制执行。也许您以匿名用户身份访问记录的视图?您可以将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以传播原始异常,然后将引用添加到您的帖子中,如果没有它,很难为您提供更多帮助。