Задать вопрос

Как правильно переопределить метод save()?

Проблема: при сохранении редактируемой записи (в админке) все записи таблицы БД, у которых public=True получают в поле published_date текущую дату-время, в тоже время все записи, у которых поле public=False получают в поле published_date 'None' (хотя в некоторые для теста руками прописал даты в published_date). Т.е. налицо обработка всех зписей таблицы при вызове save(), хотя, как пишут опытные люди, save() вызывается только для одного экземпляра (поля).

И дело не в альтернативном решении. Я хочу понять, почему происходит именно так.

Привожу полный код, т.к. другого варианта не вижу (больше в приложении кода нет):

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)


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()
  • Вопрос задан
  • 2112 просмотров
Подписаться 3 Оценить 1 комментарий
Пригласить эксперта
Ответы на вопрос 4
mututunus
@mututunus
Backend developer (Python, Golang)
Это плохая практика. Используйте сигнал pre_save.
Ответ написан
fox_12
@fox_12 Куратор тега Django
Расставляю биты, управляю заряженными частицами
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)
Ответ написан
sim3x
@sim3x
Если нужно опубликовать по дате - ясно
Если нужно опубликовать флагу - ясно

А зачем так извращаться?

Напиши менеджер, в котором записи будут показаны если какое-то из условий верно
Ответ написан
@SkiBY
Данный кусок кода работает верно. Он сохраняет время каждый раз, когда сохраняется модель, которая отмечена как опубликованная.
Почему меняются все ваши остальные записи - это уже вопрос к остальным процедурам. В данном куске, повторюсь, ничего такого нет.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы