Django及Xadmin开发代码速查

Coding Alan 8年前 (2017-02-21) 8219次浏览 0个评论 扫描二维码

注:鉴于 xadmin 的方向调整,可以考虑转为使用simpleui,界面也相当美观

https://github.com/newpanjing/simpleui

本文接Django环境搭建及开发一文,旨在记录一些常用的开发代码避免经常要到官方文档中查看(为方便操作大多在PyCharm[ Tools> Run manage.py Task…]中进行,涉及命令行的可以自行在前面添加python manage.py)。

注:如果在菜单中找不到Run manage.py Task的话,请点击Preferences>Languages & Frameworks>Django在右侧Settings处配置本项目的setting.py文件位置

另外以下内容涉及中文的如使用Python 2.x请自定添加u来指定为utf-8编码

基本操作篇

1.创建App

startapp app_name

2.在系统settings.py的INSTALLED_APPS中添加对应的app_name

class ModelName(models.Model):
# 注:xxx = models.DateTimeField(default=datetime.now)时不要在now后加括号

3.编辑所创建App下的models.py(数据表的创建)

makemigrations app_name
migrate app_name

createsuperuser创建后台登录的超级用户

4.添加url(urls.py)

from django.views.generic import TemplateView
urlpatterns = [
    url(r'^xadmin/', xadmin.site.urls),
    url(r'^$', TemplateView.as_view(template_name='index.html'), name="index"),
]

5. forms和views常用
views.py

# 反向取外键所有数据(_set)
yourObject.theModelName_set.all()
# 获取url的name并跳转
from django.core.urlresolvers import reverse
return HttpResponseRedirect(reverse('index'))

forms.py

class Meta:
    model = modelName
    fields = ['field1'...]
# 在使用ModelForm时通clean_fieldName来重写该字段验证方法, 在该方法内获取字段值:self.cleaned_data['fieldName']

Settings.py的常见修改

# 将所有app都放到apps下后的设置
import sys
sys.path.insert(0, os.path.join(BASE_DIR, 'apps'))
# 配置数据库
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql',
        'NAME': 'test',
        'USER': 'root',
        'PASSWORD': 'root',
        'HOST': '127.0.0.1',
        'OPTIONS': {
            'init_command': "SET storage_engine=INNODB;",
        },
    }
}
# 设置模板目录
TEMPLATES = [
    {
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
    },
]
# 设置文字
LANGUAGE_CODE = 'zh-hans'
# 设置时区
TIME_ZONE = 'Asia/Shanghai'
USE_TZ = False

STATICFILES_DIRS = (
    os.path.join(BASE_DIR, 'static'),
)
# 设置上传使用的media路径
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
# 同时配合的配置还有
TEMPLATES = [
    {
        'OPTIONS': {
            'context_processors': [
                ....
                'django.template.context_processors.media',
            ],
        },
    },
]
# 设置media路径时应设置urls.py
from ProjectName.settings import MEDIA_ROOT
from django.views.static import serve
url(r'^media/(?P<path>.*)$', serve, {"document_root": MEDIA_ROOT}),

用户信息表

用户信息表略有特殊之处:
models.py

from django.contrib.auth.models import AbstractUser
# 下面我们使用名称是UserProfile,但如果写用户模块,可以通过如下代码来获取对应的用户表名称
# from django.contrib.auth import get_user_model
# User = get_user_model()

class UserProfile(AbstractUser):
    nick_name = models.CharField(max_length=50, verbose_name=u"昵称", default="")
    birth_day = models.DateField(verbose_name=u"生日", null=True, blank=True)
    gender = models.CharField(max_length=6, choices=( ("male", u"男"), ("female", u"女")), verbose_name=u"性别")
    address = models.CharField(max_length=100, default=u"", null=True, blank=True, verbose_name=u"地址")
    mobile = models.CharField(max_length=11, null=True, blank=True, verbose_name=u"手机号码")
    avatar = models.ImageField(upload_to="image/%Y/%m", default=u"image/default.png", verbose_name=u"用户头像")


    class Meta:
        verbose_name = u"用户信息表"
        verbose_name_plural = verbose_name
        # db_table = 
        # ordering =

    def __unicode__(self):
        return self.username
    # model中可定义方法动态获取数据,使用时相当于所定义的字段,如以下获取未读消息数量:
    def get_unread_nums(self):
        from operation.models import UserMessage
        return UserMessage.objects.filter(id=self.id, has_read=False).count()
    # 如需在后台中显示,设置显示名称的方法如下
    get_unread_nums.short_description = "未读消息数量"
    # 扩展:使url在后台中以锚文本形式显示
    def go_to(self):
        from django.utils.safestring import mark_safe
        return mark_safe("<a href='"+self.url+"' target='_blank'>点此访问</a>")

settings.py

AUTH_USER_MODEL = "users.UserProfile"

admin.py
需要进行注册

from .models import UserProfile

class UserProfileAdmin(admin.ModelAdmin):
    pass

admin.site.register(UserProfile, UserProfileAdmin)

如果使用的是xadmin的话,常规需通过如下方式注册才不会报错
adminx.py

from xadmin.plugins.auth import UserAdmin
from .models import UserProfile

class UserProfileAdmin(UserAdmin):
    pass
    # 在此处拷贝UserAdmin中的get_form_layout可进行布局自定义

xadmin.site.register(UserProfile, UserProfileAdmin)
# 卸载原始User
from django.contrib.auth.models import User
xadmin.site.unregister(User)

但由于xadmin当前版本的bug进行上述操作会导致密码无法修改,解决的方法是注释掉前面的register和unregister部分,然后在xadmin源码的plugins/auth.py的包引用结束处添加

from django.contrib.auth import get_user_model
User = get_user_model()

并将auth.py中的site.register_view(r’^auth/user/(.+)/password/$’,修改为

site.register_view(r'^users/userprofile/(.+)/password/$'

xadmin中的常用配置

# adminx.py(更多内容可查看xadmin/plugins下的源码)
list_display # 设置默认显示字段
search_fields # 设置可搜索字段
list_filter # 设置可过滤字段
model_icon # 设置左侧导航中显示的icon
list_editable # 设置行内可编辑字段
readonly_fields # 设置字段仅可为读
exclude # 取消字段在后台表单中的显示
refresh_times = [3, 5] # 设置在后台自行选择自动刷新间隔
relfield_style = 'fk-ajax' #外键指向字段内容过多时默认不下拉通过搜索显示 
# 注:readonly_fields和exclude两者是冲突的,只能设置一个
# 设置顶部可选主题
class BaseSetting(object):
    enable_themes = True
    use_bootswatch = True

# 设置头部标题,底部信息,左侧导航样式
class GlobalSettings(object):
    site_title = "xx后台管理系统"
    site_footer = "xx网"
    menu_style = "accordion"

xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)

# 重载get_form_layout修改后台表单样式

# apps.py
# 添加verbose_name修改左侧导航显示名称
class UsersConfig(AppConfig):
    name = 'users'
    verbose_name = "用户信息"
# __init.py__:使上面的名称配置生效,也可不配置这里,在INSTALLED_APPS的引入直接写users.apps.UsersConfig
default_app_config = "users.apps.UsersConfig"


# 对于同一张表过滤在后台中分开显示
# 1.model.py中的设置:继承原model,重点是配置proxy = true
class BannerCourse(Course):
    class Meta:
        verbose_name = "轮播课程"
        verbose_name_plural = verbose_name
        proxy = True
# 2. adminx.py中的设置, 重点是重载queryset方法
class BannerCourseAdmin(object):
    ...
    def queryset(self):
        qs = super(BannerCourseAdmin, self).queryset()
        qs = qs.filter(is_banner=True)
        return qs
# 以下部分为设置在保存和新增时自己的逻辑,只需添加save_models方法
    def save_models(self):
        # 在保存课程时统计课程机构的课程数
        obj = self.new_obj
        obj.save()
        if obj.course_org is not None:
            course_org = obj.course_org
            course_org.course_nums = Course.objects.filter(course_org=course_org).count()
            course_org.save()


# inline设置
# 1.对包含外键的model进行设置,其中的Lesson为类名
class LessonInline(object):
    model = Lesson
    extra = 0

# 添加inlines,此时在后台中添加课程的同时便可以添加具体章节了
class CourseAdmin(object):
    ...
    inlines = [LessonInline]


用户登录重写

# 重写支持用户名和邮箱登录
from django.contrib.auth.backends import ModelBackend
from django.db.models import Q
class CustomBackend(ModelBackend):
    def authenticate(self, request, username=None, password=None, **kwargs):
        try:
            user = UserProfile.objects.get(Q(username=username)|Q(email=username))
            if user.check_password(password):
                return user
        except Exception as e:
            return None
# settings.py中的配置
AUTHENTICATION_BACKENDS = (
    'users.views.CustomBackend',
)

# 登录逻辑
user = authenticate(username=user_name, password=pass_word)
        if user is not None:
            login(request, user)
            ...

html模板

xxx|default_if_none:''

更多
add, addslashes, capfirst, center, cut, date, default, default_if_none, dictsort, dictsortreversed, divisibleby, escape, escapejs, filesizeformat, first, floatformat, force_escape, get_digit, iriencode, join, last, length, length_is, linebreaks, linebreaksbr, linenumbers, ljust, lower, make_list, phone2numeric, pluralize, pprint, random, rjust, safe, safeseq, slice, slugify, stringformat, striptags, time, timesince, timeuntil, title, truncatechars, truncatechars_html, truncatewords, truncatewords_html, unordered_list, upper, urlencode, urlize, urlizetrunc, wordcount, wordwrap, yesno

Xadmin集成ueditor

 

喜欢 (1)
[]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址