繁体   English   中英

Python / Django通过直通节省m2m

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM