我试图将表单数据存储到模型,当用户提交表单时,所有数据都正确保存,但多对多字段(catagory
)抛出错误。有人可以帮我编辑我的视图,以便我可以保存这些信息吗?提前谢谢你。
我想保存字段'Catagory'
但起初不能。然后我看到答案说在self.save(commit=False)
之前加self.save_m2m()
。但是这会导致另一个错误:
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/create/
Django Version: 3.2.5
Python Version: 3.9.6
Installed Applications:
['fontawesome_free',
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'jquery',
'portfolio',
'blog',
'import_export',
'tinymce',
'hitcount',
'taggit',
'accounts']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangocorehandlersexception.py", line 47, in inner
response = get_response(request)
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangocorehandlersbase.py", line 181, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangocontribauthdecorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "C:UsersBabliDesktopMy-ProjectsMySitemysiteblogviews.py", line 35, in make_post
form.save_m2m()
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangoformsmodels.py", line 451, in _save_m2m
f.save_form_data(self.instance, cleaned_data[f.name])
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangodbmodelsfieldsrelated.py", line 1668, in save_form_data
getattr(instance, self.attname).set(data)
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangodbmodelsfieldsrelated_descriptors.py", line 536, in __get__
return self.related_manager_cls(instance)
File "C:UsersBabliAppDataRoamingPythonPython39site-packagesdjangodbmodelsfieldsrelated_descriptors.py", line 851, in __init__
raise ValueError('"%r" needs to have a value for field "%s" before '
Exception Type: ValueError at /create/
Exception Value: "<Post: sadfsadfasdfsadsdfasd>" needs to have a value for field "id" before this many-to-many relationship can be used.
错误信息的截图
下面是我使用的代码片段:models.py
class Catagory(models.Model):
title = models.CharField(max_length=50)
slug = models.SlugField(max_length=400, unique=True, blank=True)
class Meta:
verbose_name_plural = "Catagories"
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Catagory, self).save(*args, **kwargs)
def __str__(self):
return self.title
@property
def num_posts(self):
return Post.objects.filter(catagory=self).count()
@property
def last_post(self):
return Post.objects.filter(catagory=self).latest("date")
class Post(models.Model):
title = models.CharField(max_length=100)
slug = models.SlugField(max_length=100, unique=True, blank=True)
user = models.ForeignKey(Author, on_delete=models.CASCADE)
content = HTMLField(max_length=500)
catagory = models.ManyToManyField(Catagory)
date = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False)
hit_count_generic = GenericRelation(HitCount, object_id_field='object_pk',
related_query_name='hit_count_generic_relation')
points = models.IntegerField(default=0)
tags = TaggableManager()
comments = models.ManyToManyField(Comment, blank=True)
forms.py
class PostForm(forms.ModelForm):
class Meta:
model = Post
fields = ['title', 'content', 'catagory', 'tags']
views.py
@login_required
def make_post(req):
context = {}
form = PostForm(req.POST or None)
if req.method == "POST":
if form.is_valid():
author = Author.objects.get(user=req.user)
form.save(commit=False)
form.save_m2m()
new_post = form
new_post.user = author
new_post.save()
return redirect('blog:blog-index')
context.update({
'form': form,
'title': 'Create A Post'
})
return render(req, 'create.html', context)
我不知道为什么会出现这个错误,它把我逼疯了
Fromdocs
:
使用commit=False的另一个副作用是当您的模型与另一个模型具有多对多关系时。如果你的模型有一个多对多关系,并且你在保存表单时指定commit=False, Django就不能立即为这个多对多关系保存表单数据。这是因为在实例存在于数据库中之前,不可能为实例保存多对多数据。
错误由以下两行引起:
form.save(commit=False)
form.save_m2m()
form.save(commit=False)
将给你一个未保存的对象,这意味着它还没有id。因此,在它之后调用form.save_m2m()
将产生您共享的错误。
这意味着您需要在调用form.save_m2m()
:
my_obj = form.save(commit=False)
my_obj.save()
form.save_m2m()
看来你想做的是:
new_post = form.save(commit=False) # unsaved new post object
new_post.user = author
new_post.save()
form.save_m2m()