我的模型如下:
class Photo(models.Model):
objects = PhotoManager()
date = models.DateField()
credit = models.CharField(max_length=60)
sites = models.ManyToManyField(Site)
tags = models.ManyToManyField('PhotoTag', related_name='photos')
caption = models.CharField(max_length=255)
timestamp = models.DateTimeField(auto_now=True)
photo_src = models.ImageField()
class PhotoTag(models.Model):
slug = models.CharField(max_length=255)
我的PhotoUploadForm的相关行
tags = forms.CharField(max_length=250)
我要做的是取标记字段,用逗号分隔成一个列表,get_or_create它们作为PhotoTag对象,然后将它们添加到当前表单中的Photo对象。可能在表单保存方法中,对吧?这样的事情(这不起作用):
def save(self, commit=True):
photo = super(PhotoUploadForm, self).save(commit=False)
tags = [x.strip() for x in photo.tags.split(',')]
photo.tags = []
for tag in tags:
tag = PhotoTag.objects.get_or_create(slugify(tag))
photo.tags.append(tag)
if commit:
photo.save()
return photo
我认为我的原则是正确的,但执行不是。我很感激指导和学习正确的思考方式!
更新了错误追溯:
Traceback:
File "/vagrant/default_env/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
111. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/vagrant/default_env/lib/python3.4/site-packages/django/contrib/auth/decorators.py" in _wrapped_view
22. return view_func(request, *args, **kwargs)
File "/vagrant/projects/bluehorse/bluehorse/apps/photos/views.py" in create_form
46. photo = form.save(commit=False)
File "/vagrant/projects/bluehorse/bluehorse/apps/photos/forms.py" in save
31. tags = [x.strip() for x in photo.tags.split(',')]
File "/vagrant/default_env/lib/python3.4/site-packages/django/db/models/fields/related.py" in __get__
1175. through=self.field.rel.through,
File "/vagrant/default_env/lib/python3.4/site-packages/django/db/models/fields/related.py" in __init__
831. (instance, source_field_name))
Exception Type: ValueError at /admin/photos/create
Exception Value: "<Photo: Photo object>" needs to have a value for field "photo" before this many-to-many relationship can be used.
答案 0 :(得分:1)
编辑:
我误解了你的问题抱歉。你这里有一些问题。第一个是这一行
[x.strip() for x in photo.tags.split(',')]
photo.tags
实际上是<{1}}
ManyToMany
返回未保存的photo = super(PhotoUploadForm, self).save(commit=False)
对象。您可能实际上想要使用
Photo
因为tags = [x.strip() for x in self.cleaned_data['tags'].split(',')]
将包含表单中的数据,并且self.clean_data
对象在您调用Photo
之后才会获取数据。
在实际在数据库中创建对象之前,不能添加save
,因为在幕后,ManyToMany
表看起来大致如下:
ManyToMany
在class Photo_PhotoTag_M2M_table(models.Model):
photo = models.ForeignKey(Photo)
phototag = models.ForeignKey(PhotoTag)
函数中,当您执行此行PhotoUploadForm.save
时,实际上会在数据库中创建Photo
对象。因此,您需要在创建表单后添加许多内容。
(https://docs.djangoproject.com/en/1.7/topics/db/examples/many_to_many/#many-to-many-relationships)
答案 1 :(得分:0)
我不知道这对表单有何用处,但是当覆盖模型的保存方法时,您无法直接访问m2m字段,必须使用m2m_changed signal。
我打赌这里也是如此,因为回溯是相似的。