A
A
Alexander2016-03-10 08:12:57
Django
Alexander, 2016-03-10 08:12:57

How to correctly override the save() method?

Problem: when saving an edited record (in the admin panel), all records in the database table that have public=True receive the current date-time in the published_date field, at the same time, all records whose field public=False receive the published_date 'None' field (although in some for the test, I wrote the dates in published_date by hand). Those. there is a processing of all table records when save () is called, although, as experienced people write, save () is called only for one instance (field).
And it's not about alternatives. I want to understand why this is happening.
I give the full code, because I don’t see another option (there is no more code in the application):
models.py:

from django.db import models
from django.utils import timezone
from ckeditor.fields import RichTextField
from ckeditor_uploader.fields import RichTextUploadingField

# Create your models here.

class Post (models.Model):
  author = models.ForeignKey('auth.User', verbose_name='Пользователь')
  title = models.CharField(max_length=200, verbose_name='Заголовок')
  alias = models.SlugField(max_length=250, verbose_name='Алиас')
  intro_text = RichTextUploadingField(verbose_name='Вступительный текст')
  text = models.TextField(verbose_name='Полный текст')
  meta_description = models.CharField(max_length=250, verbose_name='Мета-описание')
  meta_keywords = models.CharField(max_length=250, verbose_name='Мета-ключи')
  created_date = models.DateTimeField(default=timezone.now, verbose_name='Дата создания')
  published_date = models.DateTimeField(blank=True, null=True, verbose_name='Дата публикации')
  public = models.BooleanField(default=False, verbose_name='Опубликовано?')
  image = models.ImageField(blank=True, null=True, upload_to='blog/images/', verbose_name='Изображение')
  
  def published(self):
    self.published_date = timezone.now()
    self.save()

  def __str__(self):
    return self.title

  class Meta:
    verbose_name = 'Публикация'
    verbose_name_plural = 'Публикации'

  def save(self, *args, **kwargs):
    if self.public and not self.published_date:
      self.published_date = timezone.now()
    if not self.public and self.published_date:
      self.published_date = None
    super(Post, self).save(*args, **kwargs)

admin.py:
from django.contrib import admin
from .models import Post
from django.contrib.auth.models import User
from django.template.defaultfilters import truncatechars
# Register your models here.

class AdminPost(admin.ModelAdmin):
  list_display = 			['title', 'alias', 'author', 'created_date', 'public', 'published_date', 'trunc_intro_text', 'published']
  list_display_links = 	['title', 'alias', 'author', 'created_date', 'public', 'published_date', 'trunc_intro_text']
  #fields =				['title', 'alias', 'author', 'created_date', 'published_date', 'intro_text', 'text', 'meta_description', 'meta_keywords', 'image']
  def trunc_intro_text(self, obj):
    return truncatechars(obj.intro_text,80)
  trunc_intro_text.short_description='Вступительный текст'

  prepopulated_fields = {'alias': ('title',),}

admin.site.register(Post,AdminPost)

application urls.py:
"""
from django.conf.urls import url, include
from django.contrib import admin
from django.conf.urls.static import static
from django.contrib.staticfiles.urls import staticfiles_urlpatterns
from django.conf import settings

urlpatterns = [
  url(r'^admin/', include(admin.site.urls)),
  url(r'^ckeditor/', include('ckeditor_uploader.urls'))
]

urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
urlpatterns += staticfiles_urlpatterns()

Answer the question

In order to leave comments, you need to log in

4 answer(s)
A
Andrey K, 2016-03-10
@mututunus

This is bad practice. Use the pre_save signal.

V
Vladimir Kuts, 2016-03-10
@fox_12

class Post (models.Model):
    published_date = models.DateTimeField(blank=True, null=True, verbose_name='Дата публикации')
    public = models.BooleanField(default=False, verbose_name='Опубликовано?')

    def save(self, *args, **kwargs):
        if self.public:
             self.published_date = timezone.now()
        else:
             self.published_date = None
        super(Post, self).save(*args, **kwargs)

S
sim3x, 2016-03-10
@sim3x

If it is necessary to publish by date - it is clear
If it is necessary to publish a flag - it is clear
And what for so to be perverted?
Write a manager in which records will be shown if any of the conditions is true

S
SkiBY, 2016-03-10
@SkiBY

This piece of code works correctly. It saves time each time a model is saved that is marked as published.
Why all your other records change is already a question for other procedures. In this piece, I repeat, there is nothing of the kind.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question