Django使用Author自动保存模型

时间:2014-01-14 21:38:46

标签: python django django-authentication

Django 1.6拥有模型和自定义用户

在设置中

AUTH_USER_MODEL = 'magazine.Author'

models.py

# -*-coding: utf-8 -*-
from django.db import models
import re
import pytils
import datetime
from sorl.thumbnail import default
import markdown
from django.utils.encoding import force_unicode
from django.utils.safestring import mark_safe
from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
from sorl.thumbnail import ImageField
from django.conf import settings

LANDSCAPE_THUMBS_SIZE = '1200x600'
SQUARE_THUMBS_SIZE = '800x800'
PORTRAIT_THUMBS_SIZE = '800x1200'

"""
some functions heed to content processing
"""
def mark(value):
    extensions = ["nl2br", ]
    return mark_safe(markdown.markdown(force_unicode(value), extensions, safe_mode=True, enable_attributes=False))

def get_image(content, thumbs, crop=None):
    try:
        firstImage = re.findall(r'(?mu)\[(?P<title>.*)\s*\]\((?P<url>.*)\s*\)', content)
        title = firstImage[0][0]
        url = firstImage[0][1]
        if crop:
            thumb = default.backend.get_thumbnail(firstImage[0][1], thumbs, crop=crop)
        else:
            thumb = default.backend.get_thumbnail(firstImage[0][1], thumbs)
        return { 'url' : thumb.url, 'title': title }
    except:
        return None


"""
Users
"""
class AuthorManager(BaseUserManager):
    def create_user(self, email, password=None):
        if not email:
            raise ValueError('Users must have an email address')

        user = self.model(
            email=AuthorManager.normalize_email(email),
        )

        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, email, password):
        user = self.create_user(email,
            password=password,
        )
        user.is_admin = True
        user.save(using=self._db)
        return user

class Author(AbstractBaseUser):
    email = models.EmailField(max_length=254, unique=True, db_index=True)

    is_active = models.BooleanField(default=True)
    is_admin = models.BooleanField(default=False)

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = []

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

    def __unicode__(self):
        return self.email

    def has_perm(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    objects = AuthorManager()

    @property
    def is_staff(self):
        return self.is_admin

"""
Articles classes
"""

class Category(models.Model):
    title = models.CharField(max_length=300, help_text="Заголовок")
    slug = models.SlugField(unique=True, help_text="Ссылка")

    def get_absolute_url(self):
        return '/category/%s/' % self.slug

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ['title']
        verbose_name_plural = "Категория"

    def save(self, *args, **kwargs):
        self.slug = pytils.translit.slugify(self.title)
        super(Category, self).save(*args, **kwargs)


class Post(models.Model):

    title = models.CharField(u'Имя', max_length=500, help_text=u'Мелкие')
    slug = models.SlugField(unique=True, help_text="Ссылка")
    content = models.TextField(u'Описание', help_text=u'Колье, серебро, большой текст.. Markdown', blank=True) 
    date = models.DateTimeField('Дата', default=datetime.datetime.now)
    category = models.ForeignKey('Category', related_name="category")
    tags = models.CharField(u'Тэги', max_length=500, help_text=u'Разделенные ","', blank=True)

    TYPE_OF_POST = (
        ('story', 'История'),
        ('interview', 'Беседа'),
        ('photo', 'Фото'),
    )
    type_post = models.CharField("Тип Записи", max_length=20, default='interview', choices=TYPE_OF_POST)
    author = models.ForeignKey(settings.AUTH_USER_MODEL)

    # standart
    def get_image_landscape(self):
        return get_image(self.content, LANDSCAPE_THUMBS_SIZE, crop='center')

    # standart
    def get_image_portrait(self):
        return get_image(self.content, PORTRAIT_THUMBS_SIZE, crop='center')

    # index small
    def get_image_square(self):
        return get_image(self.content, SQUARE_THUMBS_SIZE, crop='center')

    # content
    def get_content(self):
        return mark(self.content)

    # main preview
    def get_preview(self):
        content = re.sub(r'!(?mu)\[(?P<title>.*)\s*\]\((?P<url>.*)\s*\)', r'', self.content)
        if len(content.split('\n')) > 2:
            return mark(content.split('\n')[0])
        else:
            return mark(content)

    def get_tags(self):
        tags = re.split(", ", self.tags)
        tags_list = [dict(zip(("name", "url"), (i, pytils.translit.slugify(i)))) for i in tags]
        return tags_list

    def get_description(self):
        if '!more' in self.post:
            post = self.post.replace('!more', '<!--more-->')
            more = u'<div class="post_more"><a href="/%s/">Подробности..</a></div>' % self.slug
            a = post.split("<!--more-->")
            a.insert(1, more)
            return a[0] + a[1]
        else:
            return self.post

    def get_absolute_url(self):
        return '/%s/' % self.slug

    def __unicode__(self):
        return self.title

    class Meta:
        ordering = ['-date']
        verbose_name_plural = "Запись"
        unique_together = ('title', 'content')

    def save(self, *args, **kwargs):
        self.slug = pytils.translit.slugify(self.title)
        super(Post, self).save(*args, **kwargs)

和admin.py

# -*- coding: utf-8 -*-
from models import Category, Post, Author
from django.contrib import admin


class CategoryAdmin(admin.ModelAdmin):
    fieldsets = (        
        ('Содержание', {
            'fields': ('title',)
        }),
    )

class PostAdmin(admin.ModelAdmin):
    prepopulated_fields = {'slug': ('title',)}

    fieldsets = (        
        ('Дополнительно', {
            'classes': ('collapse',),
            'fields': ('slug', 'date')
        }),
        ('Содержание', {
            'fields': ('type_post', 'title', 'content', 'category', 'tags')
        }),
    )
    list_display = ('title', 'date')
    list_per_page = 15


admin.site.register(Category, CategoryAdmin)
admin.site.register(Post, PostAdmin)

admin.site.register(Author)

然后我尝试保存模型,我收到错误。

magazine_post.author_id may not be NULL

我尝试这样做https://docs.djangoproject.com/en/dev/topics/auth/customizing/#substituting-a-custom-user-model

但结果有相同的错误.. :(

https://www.monosnap.com/image/4BbZOPjTNmVORVTfSEKujFMmlvCxfF&amp;完整跟踪http://paste.in.ua/9264/

2 个答案:

答案 0 :(得分:1)

您的问题是:

class PostAdmin(admin.ModelAdmin):
    ...

没有author字段,而且是必需字段。

现在,当您从管理员保存模型时,author字段为NULL,并且根据数据库,它不可为空。因此错误。

现在,要解决此问题,请在author admin

中添加Post字段作为字段

答案 1 :(得分:0)

惊人地解决了这个问题 - django-custom-user