首页 > 解决方案 > Django 无法返回基于类的视图用户 ID

问题描述

我的目标是使用 ajax 更新视图。当用户在这 3 个字段中输入一个值并将这些字段保存到该用户的数据库中时。我有一个带有 3 个文本字段的用户模型,如下所示

class Q3Sign(models.Model):
title = models.CharField(max_length =255,blank =True)
title2 = models.CharField(max_length =255, blank = True)
title3 = models.CharField(max_length =255,blank =True)
user = models.ForeignKey(User, on_delete=models.CASCADE )

class Meta:
    db_table = "Q3sign"

我的观点是,当我尝试填充字段时出现以下错误。django.db.utils.IntegrityError:NOT NULL 约束失败:Q3sign.user_id

class Createcourse(generic.CreateView):
    model = Q3Sign
    fields = ['title','title2','title3']
    template_name = 'Q3canA/create_course.html'
    success_url = reverse_lazy('create_course')


    def create_course(self, request):
        members = Q3Sign.objects.all()
        return render (request,'Q3canA/create_course.html' , {'members':members})
    
def insert(request):
        member = Q3Sign(title=request.POST['title'], title2=request.POST['title2'], 
        title3=request.POST['title3'], user=request.POST['user.id'])
        member.save()
        return redirect('create_course')

这是我的html

      <div class="container">
        <h2>Courses</h2>
        <form method=post>
          {% csrf_token %}
          {{ form.as_p}}
          <input type="submit" value="Create course" />
        </form>

      </div>
      <form method="post">
          {% csrf_token %}
          <div class="form-inline">
              <label>Course 1</label>
              <input type="text" id="title" name="title" class="form-control"/>
          </div>
      <br />
      <div class="form-inline">
              <label>Course 2</label>
                 <input type="text" id="title2" name="title2" class="form-control"/>
              <label>Course 3</label>
              <input type="text" id="title3" name="title3" class="form-control"/>
          </div>
          <br />
          <div class="col-md-4"></div>
          <div class="col-md-4 form-group">
      <button type="button" class="btn btn-primary form-control" id="submit">Submit</button>
          </div>
      </form>
      <hr style="border-top:1px solid #000; clear: both;" />
      <table class"table table-bordered">
        <thead class = "alert-warning">
          <tr>
            <th>Course 1</th>
            <th>Course 2</th>
            <th>Course 3</th>
          </tr>
        </thead>
        <tbody>
          {% for member in members %}
          <tr>
            <td></td>
            <td>{{member.user.id}}</td>
            <td>{{member.title}}</td>
            <td>{{member.title2}}</td>
            <td>{{member.title3}}</td>
          </tr>
          {% endfor%}
        </tbody>
      </table>



      {% endblock %}

现在更新字段消失了: 在此处输入图像描述

这是我的网址

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',views.home, name='home'),
    #Auth
    path('signup', views.Signup.as_view(), name = 'signup'),
    path('login', auth_view.LoginView.as_view(), name = 'login'),
    path('logout', auth_view.LogoutView.as_view(), name = 'logout'),

    #Q3Course

    path('createcourse',views.Createcourse.as_view(), name = 'create_course'),
    url(r'^create_course', views.Createcourse.createcourse, name='create_course'),



]

urlpatterns +=  static(settings.STATIC_URL,document_root=settings.STATIC_ROOT)

感谢@Fifon,代码现在可以工作了。我需要了解的唯一问题是为什么 if 语句不起作用。如果字段为空或包含测试,它仍将其保存在数据库中,而不是在 if 子句中发出警报?

$(document).ready(function(){
    $('#submit').on('click', function(){

        $title = $('#title').val();
        $title2 = $('#title2').val();
        $title3 = $('#title3').val();
        $user = $('#user').val();


        if($title.toLowerCase().indexOf('test') == -1 || $title2 == "" || $title3 == "" || $user = ""){
            alert("Please complete field");
        }else{
            $.ajax({
                type: "POST",
                url: "/create_course",
                data:{
                    title: $title,
                    title2: $title2,
                    title3: $title3,
                    user: $user,
                    csrfmiddlewaretoken: $('input[name=csrfmiddlewaretoken]').val()
                },
                success: function(){
                    alert('Save Data');
                    $('#title').val('');
                    $('#title2').val('');
                    $('#title3').val('');
                    $('#user').val('');

                    window.location = "/create_course";
                }
            });
        }
    });
});

标签: django

解决方案


首先,不需要您的 insert() 方法。由于您有一个 CreateView,您应该使用它,它将处理创建您的对象并将它们插入到数据库中。您应该使用 CreateView 为您提供的表单,而不是手动为表单创建 HTML。这将使您的生活更轻松,并确保进行适当的验证。像这样的东西:

<form method="POST" id="create-course-form">
    {% csrf_token %}
    {{ form.as_p}}
    <input type="submit" value="Create course" />
</form>

您的 HTML 现在有点令人困惑——有一个使用 {{ form.as_p }} 模板标签呈现的表单,以及一个手动呈现的表单。请注意这里。

在您的 AJAX 调用中,您应该将表单数据提交到与您的 CreateView 关联的 URL。我看不到您的 urls.py,但例如:

$.ajax({
    type: "POST",
    url: "{% url 'course-create' %}",
    data: $('#create-course-form').serialize(),
    ...

您还需要使用 preventDefault() 确保表单不会通过普通的 POST 请求(您想使用 AJAX)提交:

$('#create-course-form').submit(function(e){
    e.preventDefault();
    ...

把它们放在一起,回到你的 Createcourse 视图,你应该定义 form_valid(self) 方法,这样你就可以添加用户信息。当您使用 AJAX 时,您需要返回一个 JsonResponse。例如:

def form_valid(self, form):
    if self.request.is_ajax():
        self.object = form.save(commit=False)
        self.object.user = request.user
        self.object.save()

        return JsonResponse({'success':True})
    else:
        return super(CreateView, self).form_valid(form)

您还需要处理您的表单无效的情况,如下所示:

def form_invalid(self, form):
    if self.request.is_ajax():
        return JsonResponse(form.errors, status=400)
    else:
        return super(CreateView, self).form_invalid(form)

最后,您需要在 JavaScript 中处理响应。成功并不一定意味着表格有效并且课程已创建。如果有错误,您需要将它们显示给用户。

更新:您有两个都称为“create_view”的 URL。删除第二个。一切都可以从一个 CreateView (Createcourse) 中完成。为了仍然可以访问“成员”,请按如下方式定义 get_context_data():

def get_context_data(self, **kwargs):
    context = super().get_context_data(**kwargs)
    context["members"] = Q3Sign.objects.all()
    return context

推荐阅读