具有OnetoOne字段的Django CreateView / UpdateView,具体取决于记录是否存在

时间:2017-08-19 16:10:59

标签: django django-forms django-views

我正在尝试构建个人资料页面,其中User可以填写Teacher模型。

我的教师模型, model.py

class Teacher(models.Model):
    user = models.OneToOneField(User, on_delete=models.PROTECT, related_name='Teacher')
    rate = models.CharField(max_length=200)
    availability = models.BooleanField(default=False)

forms.py

class TeacherCreate(CreateView):
    user_id = request.user.id #INCORRECT! Needs something to remember current user id.
    model = Teacher
    fields = ['rate','availability']
编辑:我也尝试添加:

def form_valid(self, form):
    form.instance.user = self.request.user
    return super(TeacherCreate, self).form_valid(form)

as suggested here.

我们不允许用户在此创建视图中更改其ID。事实上,我认为这应该是user_id提供的当前用户ID request.user.id

teacher_form.html

    <form action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
    {% for field in form %}
<div class="form-group">
    <span color="red">{{ field.errors }}</span>
    <label>
        {{ field.label_tag }}
    </label>
    <div>{{ field }}</div>
</div>
{%  endfor %}
     <button type="submit">Submit</button>
    </form>

现在的问题是,当我运行它时,我收到错误:

  

NOT NULL约束失败:users_teacher.user_id

我认为是因为我没有指定user_id。

我希望它如何运作:

首先,检查教师是否已在数据库中有记录。例如。如果Teacher表中有一行,则user_id =当前用户。

如果教师有个人资料 - &gt;调用更新视图。

如果教师没有个人资料 - &gt;使用创建视图。

1 个答案:

答案 0 :(得分:1)

如果我理解,请尝试将LoginRequiredMixin添加到您的视图中,简单创建或更新视图:

from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect
from django.views.generic import CreateView


class TeacherCreate(LoginRequiredMixin, CreateView):
    model = Teacher
    fields = ['rate','availability']

    def get_success_url(self):
        # replace url name 'users' on your if need
        return reverse('users',args=(self.request.user.id,))

    def form_valid(self, form):
        user = self.request.user
        instance, _ = Teacher.objects.get_or_create(user=user)
        instance.rate = form.cleaned_data.get("rate", "")
        instance.availability = form.cleaned_data.get("availability", "")
        instance.save()
        # modify return
        return HttpResponseRedirect(self.get_success_url())