注:鉴于 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
1 | startapp app_name |
2.在系统settings.py的INSTALLED_APPS中添加对应的app_name
1 2 | class ModelName(models.Model): # 注:xxx = models.DateTimeField( default =datetime.now)时不要在now后加括号 |
3.编辑所创建App下的models.py(数据表的创建)
1 2 | makemigrations app_name migrate app_name |
createsuperuser创建后台登录的超级用户
4.添加url(urls.py)
1 2 3 4 5 | 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
1 2 3 4 5 | # 反向取外键所有数据(_set) yourObject.theModelName_set.all() # 获取url的name并跳转 from django.core.urlresolvers import reverse return HttpResponseRedirect(reverse( 'index' )) |
forms.py
1 2 3 4 | class Meta: model = modelName fields = [ 'field1' ...] # 在使用ModelForm时通clean_fieldName来重写该字段验证方法, 在该方法内获取字段值:self.cleaned_data[ 'fieldName' ] |
Settings.py的常见修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | # 将所有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
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | 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
1 | AUTH_USER_MODEL = "users.UserProfile" |
admin.py
需要进行注册
1 2 3 4 5 6 | from .models import UserProfile class UserProfileAdmin(admin.ModelAdmin): pass admin.site.register(UserProfile, UserProfileAdmin) |
如果使用的是xadmin的话,常规需通过如下方式注册才不会报错
adminx.py
1 2 3 4 5 6 7 8 9 10 11 | 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的包引用结束处添加
1 2 | from django.contrib.auth import get_user_model User = get_user_model() |
并将auth.py中的site.register_view(r’^auth/user/(.+)/password/$’,修改为
1 | site.register_view(r '^users/userprofile/(.+)/password/$' |
xadmin中的常用配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | # 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] |
用户登录重写
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | # 重写支持用户名和邮箱登录 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模板
1 | 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