[英]Python/Django Saving m2m with Through
更新 :我创建了一个github仓库,其中包含问题的完整站点演示。 也许我下面的描述并没有完全传达我想要做的事情。
github repo是: https : //github.com/theCodeJerk/m2m-through
下面的代码被删除以说明问题。 虽然有些事情你可能想说“你为什么要这样做”,但在更大的背景下可能有一个原因:)
这是我的观点:
class SubmissionCreate(CreateView):
model = Submission
fields = '__all__'
template_name_suffix = '_create_form'
success_url = '/'
这是相关的models.py代码:
def custom_filename(instance, filename):
author = instance.publishers[0]
return 'papers/{0}.pdf'.format(author.pseudonum)
class Submission(models.Model):
name = models.CharField(
max_length=200,
blank=False
)
upload = models.FileField(
blank=True,
upload_to=custom_filename
)
publishers = models.ManyToManyField(
'Publisher',
blank=False,
related_name='publisher_of',
through='SubmissionPublisher'
)
class Publisher(models.Model):
user = models.ForeignKey(
User, blank=False,
on_delete=models.CASCADE
)
pseudonym = models.CharField(
max_length=200,
blank=False
)
class SubmissionPublisher(models.Model):
publisher = models.ForeignKey(
'Publisher',
blank=False,
on_delete=models.CASCADE
)
submission = models.ForeignKey(
'Submission',
blank=False,
on_delete=models.CASCADE
)
问题出在custom_filename中,因为我需要实例中的第一个发布者来生成文件名。 当SubmissionPublisher需要保存时,尚未保存提交。
最好的办法是什么? 希望我在这里有道理。
谢谢你的帮助!
也许你可以尝试这样:
首先,更新custom_filename
方法:
def custom_filename(instance, filename):
if instance: authors = instance.publishers.all() if authors.exists():
author = authors[0]
return 'papers/{0}.pdf'.format(author.pseudonum)
return filename
在这里,我修复了一些问题,例如在您的代码instances.publishers[0]
不起作用,因为您需要使用queryset方法(如all()
或filter()
等)来访问Publisher
实例。
然后,使upload
字段可以为空 。 因为您无法在不创建Submission
实例的情况下创建M2M关系,并且无法创建upload
非空的Submission
实例,因为它需要图像。
class Submission(models.Model):
name = models.CharField(
max_length=200,
blank=False
)
upload = models.FileField(
null=True, default=None,
blank=True,
upload_to=custom_filename
)
然后,创建一个Form
并覆盖save
方法:
from django import forms
from .models import Submission
class SubmissionForm(forms.ModelForm):
class Meta:
model = Submission
fields = '__all__'
def save(self, commit=True):
uploaded_file = self.cleaned_data.pop('upload')
instance = super().save(commit=True)
instance.upload = uploaded_file instance.save()
return instance
在这里,我将提取upload
值并首先保存实例。 然后放置图像。 此代码将起作用,因为upload
字段在您的Submission
模型中可以为空 。
最后,在SubmissionCreate
视图中使用该表单类:
class SubmissionCreate(CreateView):
model = Submission
form_class = SubmissionForm
template_name_suffix = '_create_form'
success_url = '/'
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.