简体   繁体   English

Django:如何根据表单的非持久字段自定义保存模型/表单?

[英]Django: How to custom save a model/form based on a non-persistent field of a form?

I'm reposting this question since I asked 2 in 1 in a previous post. 由于我在上一篇文章中以2合1的比例提出要求,因此我重新发布了此问题。

I want to set the field publication_date in the Entry model to change when the boolean to_publish is set to true, something like the custom save() method in the model, but I haven't been able to do that on the form. 我想在布尔模型to_publish设置为true时,将Entry模型中的字段Publication_date设置为更改,类似于模型中的自定义save()方法,但是我无法在表单上执行此操作。

#blog/models.py
class Entry(models.Model):
    title = models.CharField(max_length=100)
    body = models.TextField()
    slug = models.SlugField(max_length=100, unique=True)
    creation_date = models.DateTimeField(editable=False)
    publication_date = models.DateTimeField(editable=False, null=True)
    modification_date = models.DateTimeField(editable=False)

    author = models.ForeignKey(User)
    categories = models.ManyToManyField(Category)
    tags = models.ManyToManyField(Tag)

    objects = EntryQuerySet.as_manager()

    def __str__(self):
        return self.title

    def was_published_recently(self):
        now = datetime.datetime.now()
        return now - datetime.timedelta(days=1) <= self.publication_date <= now

    def is_published(self):
        return self.publication_date is not False

    is_published.boolean = True
    is_published.short_description = 'Is it Published?'

    def get_absolute_url(self):
        return reverse("entry_detail", kwargs={"slug": self.slug})

    class Meta():
        verbose_name = "Blog Entry"
        verbose_name_plural = "Blog Entries"
        ordering = ['-creation_date']

    def save(self, *args, **kwargs):
        """ On save, update timestamps """
        if not self.id:
            self.creation_date = datetime.datetime.now()
        self.modification_date = datetime.datetime.now()
        return super(Entry, self).save(*args, **kwargs)

#blog/forms.py
class EntryAdminForm(forms.ModelForm):
    to_publish = forms.BooleanField(required=False)

    class Meta:
        model = Entry
        fields = ['title', 'body', 'slug', 'author', 'categories', 'tags']

#blog/admin.py
class EntryAdmin(MarkdownModelAdmin):
    form = EntryAdminForm
    list_display = ("title", "author", "creation_date", "publication_date", "is_published")
    prepopulated_fields = {"slug": ("title",)}
    formfield_overrides = {TextField: {'widget': AdminMarkdownWidget}}

Thank you. 谢谢。

Override the save_model() method of the EntryAdmin : 覆盖save_model()的方法EntryAdmin

class EntryAdmin(MarkdownModelAdmin):
    ...
    def save_model(self, request, obj, form, change):
        if form.cleaned_data.get('to_publish'):
            obj.publication_date = datetime.now()
        obj.save()

The other (and more complex) option is to override the EntryAdminForm.save() method: 另一个(也是更复杂的)选项是重写EntryAdminForm.save()方法:

class EntryAdminForm(forms.ModelForm):
    ....
    def save(self, *args, **kwargs):
        entry = super(EntryAdminForm, self).save(*args, **kwargs)
        if self.cleaned_data.get('to_publish'):
            entry.publication_date = datetime.now()
            if kwargs.get('commit', True):
                entry.save()
        return entry

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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