使用表单创建新对象的问题(Django)



我正在使用Django框架来建立一个网站。这个网站是基于用户的,每个用户都有一个配置文件模型。现在,我正在建立一个系统,每个用户都可以输入他们的工作经验。我希望它能让你输入一个类别,然后为每个类别填写分数。(例如,如果你为《纽约时报》写文章,分类将是"纽约时报";然后在它的正下方是你用项目符号写的文章。我在这个阶段,我只是试图使它,以便用户可以创建一个新的类别。我有一个编辑配置文件页面,用户已经可以从模型中编辑一些细节。我试着添加一个表单来创建一个新类别。当你提交的类别,一个成功的消息显示,但当我看我的管理面板,它不创建类别下的对象。下面是代码:(注意:此表单允许您为类别选择用户,稍后我必须更改它,以便将类别设置为当前登录的用户)

views.py:

from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import ListView
from django.contrib.auth.models import User 

from django.urls import reverse_lazy
from .models import Social, Category
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
from .forms import(
UserRegisterForm,
UserUpdateForm,
ProfileUpdateForm,
BiographyForm,
AccessCodeForm,
AddCategory,
)
from django.apps import apps
Post = apps.get_model('blog', 'Post')
@login_required
def profile(request):
if request.method == 'POST':
u_form = UserUpdateForm(request.POST, instance=request.user)
p_form = ProfileUpdateForm(request.POST,
request.FILES, 
instance=request.user.profile)
b_form = BiographyForm(request.POST, instance=request.user.profile)
c_form = AddCategory(request.POST, request.FILES, instance=request.user)
if u_form.is_valid() and p_form.is_valid() and b_form.is_valid and c_form.is_valid():
u_form.save()
p_form.save()
b_form.save()
c_form.save()
messages.success(request, f'Your account has been updated!')
return redirect('editprofile')
else:
u_form = UserUpdateForm(instance=request.user)
p_form = ProfileUpdateForm(instance=request.user.profile)
b_form = BiographyForm(instance=request.user.profile)
c_form = AddCategory(instance=request.user)

context = {
'u_form': u_form,
'p_form': p_form,
'b_form': b_form,
'c_form': c_form
}
return render(request, 'users/editprofile.html', context)

models.py:

from django.db import models
from django.contrib.auth.models import User
from PIL import Image
class Category(models.Model):
user = models.ForeignKey(User, on_delete=models.DO_NOTHING, null=True, blank=True)
name = models.CharField(max_length=100)
date = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True)

def __str__(self):
return self.name
class Work(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
name = models.CharField(max_length=100)
link = models.URLField(max_length=200, blank=True, default='') 
date = models.DateTimeField(auto_now=False, auto_now_add=False, null=True, blank=True)
category = models.ForeignKey(Category, on_delete=models.DO_NOTHING, null=True, blank=True)

def __str__(self):
return self.name

editprofile.html:

{% extends "blog/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<div class="media">
<img style= "float:left" src="{{ user.profile.image.url }}" width="75" height="75">
<div class="media-body">
<h2 class="account-heading">&nbsp;&nbsp;{{ user.username }}</h2>
<p class="text-secondary">&nbsp;&emsp;{{ user.email }}</p>
</div>
</div>
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Profile Info</legend>
{{ u_form|crispy }}
{{ p_form|crispy }}
{{ b_form|crispy }}  
{{ c_form|crispy }}     
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit" action="Edit">Update</button>
</div>
</form>
</div>
{% endblock content %}

forms.py:

from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
from .models import Profile, Social, Category, Work
class AddCategory(forms.ModelForm):

class Meta:
model = Category
fields = ['name', 'date', 'user']

上面的代码不起作用,它没有创建一个新类别。然而,我尝试了一个不同的方法,它可以成功地创建一个新类别。我创建了一个新的页面和一个新的视图来显示一个单一的类别表单。此表单还将用户设置为登录的用户。

views.py(第二个方法):

class CreateCategory(LoginRequiredMixin, CreateView):
model = Category
fields = ['name', 'date']
success_url = reverse_lazy('editprofile')
def form_valid(self, form):
form.instance.user = self.request.user
return super(CreateCategory, self).form_valid(form)

category_form.html(第二种方法):

{% extends "blog/base.html" %}
{% block content %}

<h1> Category Form </h1>
<div>
<form method="POST" action="">
{% csrf_token %}
{{form.as_p}}
<input class="button" type="submit" value="Submit">
</form>
</div>
{% endblock content %}

第二个方法成功地创建了一个类别,我可以在管理页面上看到它。我更愿意有editprofile.html与所有其他形式的类别创建。我不确定为什么第一种方法不起作用。我相信这与我的views.py和模型是如何建立的有关。如果我能以某种方式将第二种方法集成到editprofile.html中,那也会工作得很好。

任何帮助或见解都是感激的。

根据你的AddCategory表单,它的模型是Category。所以当你传递实例参数时它必须是类别模型的实例,但你发送的是request。user

我认为它应该类似于:(在这种情况下,您正在发送分配给用户的最后一个类别)

c_form = AddCategory(request.POST, request.FILES, instance=request.user.category_set.last())

最新更新