返回文章列表文章索引阅读全文
STARBLOG / 阅读手记
Django

Django Rapid Development Practice: A Guide to the DRF Framework and xadmin Configuration

Steps Since this is rapid development, I won't beat around the bush—straight to the steps: Install Django Install Django Rest Framework Define models Define Rest framework serializers Define Rest framework viewsets Configure the Rest framework router Configure the admin backend Write templates and corresponding views as needed After these steps you'll have a website with a complete backend

曦远 (DealiAxy)约 30 分钟
目录12 个章节

Steps

Since this is rapid development, I won't beat around the bush—straight to the steps:

  • Install Django
  • Install Django Rest Framework
  • Define models
  • Define Rest framework serializers
  • Define Rest framework viewsets
  • Configure the Rest framework router
  • Configure the admin backend
  • Write templates and corresponding views as needed

After these steps you'll have a website with a complete backend API and an admin management interface; if you write templates, you can cover the frontend work as well.

Next I'll record my development practice in the order mentioned above.

Define models

Doesn't seem like there's much to say. Django 3 added a few new features; you can define choices with a class, which is more convenient than the old tuple definition. Other than that, nothing much. Oh right, when defining ManyToMany it's best to set a related_name, which makes reverse lookups in code easier later.

Define serializers

This is really simple: just tell the framework which fields of the model you need to serialize. Official docs: https://www.django-rest-framework.org/tutorial/1-serialization/

Code example:

from .models import *
from rest_framework import serializers

class StudentSerializer(serializers.ModelSerializer):
    class Meta:
        model = Student
        fields = ['name', 'gender', 'number', 'faculty', 'major', 'year']

Here's the model code for this Student:

class Student(models.Model):
    name = models.CharField('姓名', max_length=10)
    gender = models.IntegerField('性别', default=1, choices=GenderChoices)
    number = models.CharField('学号', max_length=20, blank=True)
    faculty = models.CharField('学院', max_length=20, blank=True)
    major = models.CharField('专业', max_length=20, blank=True)
    year = models.CharField('届别', max_length=4)

    def __str__(self):
        return self.name

Define viewsets

It's just wiring the queryset and serializers together.

Here's the code, corresponding to the student serializers above.

from rest_framework import viewsets
from .models import *
from .serializers import *

class StudentViewSet(viewsets.ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer

Configure the router

You can think of it as Rest Framework's urls configuration.

Code:

from rest_framework import routers
from core import views

router = routers.DefaultRouter()
router.register('user', views.UserViewSet)

Then add it to Django's urls configuration:

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),  # 这里
    path('api-auth/', include('rest_framework.urls')),  # 和这里
]

Clean and neat. This router should be nestable like urls, but I haven't studied Rest Framework in depth, so I don't know about that; I'll check the docs later if I need it.

Simple reference docs for drf:

Configure the admin backend

This step can actually be done earlier, right after you've defined the models, which makes managing data convenient.

Django's built-in admin is pretty powerful and can save a lot of admin backend development work for small and medium-sized sites, but the default UI is pretty ugly—anyone who's used it knows that. You still want to use it though, so what do you do? Beautify it, of course. I used to only know about the xadmin library, developed by a Chinese author, based on a Bootstrap 3 UI, rewriting the entire admin codebase. The UI looks a lot better, but unfortunately there are lots of bugs, and there's almost no documentation; implementing many features you can only go read the code. The experience is terrible and seriously hurts development efficiency… (but for a nicer UI I still had to use it at first) For details on Django configuration, you can check Liu Jiang's blog; it's very thorough, in the first reference link below~

The UI looks roughly like this:

Then I found a new xadmin alternative called simpleui, which claims to be written with Vue + Element UI. The UI is pretty good too. As for the actual experience, emmm… it and xadmin each have their strengths. But this thing has a pro version, i.e. a paid edition, so if the open-source free version works, just quietly enjoy it—you know what I mean.

The UI is as follows, and you can switch themes too.

If you're interested, take a look at the official GitHub: https://github.com/newpanjing/simpleui

Install xadmin

Django-xadmin doesn't seem to be maintained anymore; at least on GitHub it looks like the author went off to write a pure-frontend xadmin framework, and installing it is also a whole ordeal. You can't just pip install it, because that's xadmin's 0.x version, which supports Django 1.x. You need to install xadmin's django2 branch to support Django 2.x. Then I started using Django 3, and this thing apparently also has compatibility issues with Django 3…

So how should you actually install it? The simpler method is what the official GitHub says:

pip install git+git://github.com/sshwsfc/xadmin.git@django2

But this method sometimes works and sometimes doesn't; GitHub might be blocked, sigh. So there's another method: install a packaged wheel file. Download the code from the official xadmin repo, then checkout the django2 branch, then run a command to package it into a wheel file, and then you can pip install it. When I have time I'll upload it to PyPI to make it easier for anyone who needs it.

After installing, running it may still throw an error: TypeError: render() got an unexpected keyword argument 'renderer'. The cause is an error when integrating DjangoUeditor; you need to modify the boundfield.py file in the virtualenv, located at venv/lib/python3.6/site-packages/django/forms/boundfield.py. The change:

89        return widget.render(
90            name=self.html_initial_name if only_initial else self.html_name,
91            value=self.value(),
92            attrs=attrs,
93            # renderer=self.form.renderer,(93行处注释掉,就能正常运行了)
94        )

xadmin configuration

xadmin's configuration is similar to Django's, but there are a few small differences. Luckily it supports Django's messages framework; simpleui doesn't seem to… toxic

Django admin configuration is written in the admin.py file under each app; xadmin has to be written in adminx.py, and it also doesn't seem possible to register admin classes with decorators like Django. The code below shows how to register an admin:

xadmin.site.register(model类, admin类)

Note that xadmin's admin class also cannot inherit the ModelAdmin class like Django; it can only inherit BaseAdminObject or just not write anything. Looking at xadmin's source, it inherits from object (same as not writing anything)

The example below is quite complete, covering configuration of various attributes.

class CourseAdmin(object):
    '''课程'''
    list_display = [ 'name','desc','detail','degree','learn_times','students']   #显示的字段
    search_fields = ['name', 'desc', 'detail', 'degree', 'students']             #搜索字段
    list_filter = [ 'name','desc','detail','degree','learn_times','students']    #过滤字段
    model_icon = 'fa fa-book'            #自定义图标
    ordering = ['-click_nums']           #排序功能
    readonly_fields = ['click_nums']     #只读字段,不能编辑
    exclude = ['fav_nums']               #不显示的字段
    inlines = [LessonInline,CourseResourceInline]    #增加章节和课程资源
    list_editable = ['degree','desc'] #在列表页可以直接编辑的
    list_display = ['get_zj_nums']  #直接使用函数名作为字段显示
    list_display = ['go_to']  # 跳转到上面定义的地址
    refresh_times = [3,5]           #自动刷新(里面是秒数)可选3或5秒

Details of admin class attributes

  • model_icon: The icons use Font Awesome icons, but this site doesn't seem accessible in China, so we use the domestic version instead, http://www.fontawesome.com.cn/icons-ui/
  • inlines configuration is similar to Django's, but you can't inherit xxxinline parent classes like Django… To define them, refer to the code below:
class LessonInline(object):
    model = Lesson
    extra = 0

class CourseResourceInline(object):
    model = CourseResource
    extra = 0
  • There's also a chart feature, but I don't think it's useful; mainly, if you change the x-axis to a char field it won't display, which is annoying. Example:
data_charts = {
        "user_count": {'title': u"course_num", "x-field": "addtime", "y-field": ("course_num"),
                       "order": ('addtime',)
        }
}

It looks like this:

Overriding some methods of the admin class

Why override? Of course to customize some operations. For example, when saving user info you want to validate certain fields, save only if they pass, and show a prompt if they don't. How? Override the parent class methods!

Code example:

class ExamineAdmin(BaseAdminObject):
    .......

    def save_models(self):
        # 获取保存的新对象
        obj = self.new_obj
        # 获取原来的对象,如果是创建新对象,则org_obj为空
        org_obj = self.org_obj

        if 不满足条件:
            self.message_user(message="不满足xxx条件", level='error')
        else:
            return super().save_models()

That's about it. Displaying messages is basically sufficient, but even if it shows a “does not meet xxx conditions” message and does not save this model object, a save-success message still appears. xadmin doesn't seem to provide an API to turn this off, and the docs don't mention it at all. To solve this problem you'll still have to dig through the xadmin source yourself; otherwise relying on search and documentation is completely a black-box operation... I'm speechless

References:

Closing Remarks

I have to say, developing websites with Python Django is extremely efficient. You can conveniently put together a usable API plus admin backend, more than enough for all kinds of course projects and simple outsourcing jobs. There's also plenty of related material; if you're willing to learn, spending some time to master commercial website development is entirely within reach! As for people questioning Python's performance, Instagram's backend is built entirely with Django—that hundreds-of-millions user scale is no joke. After getting to know a technology, diving in to study and improve is far more useful than spending all day chasing flashy trends...

That said, after reading a lot of .NET Core blogs and Zhihu questions recently, I'm still optimistic about the future of .NET Core 5. Next I'll spend some time continuing to learn C#, even though work might involve more C++... (flees)

Welcome to Discuss

For questions, please leave a message on the WeChat official account backend. I'll reply to every message~

_EOF_

Django Rapid Development Practice: A Guide to the DRF Framework and xadmin Configuration

本文作者:
程序设计实验室
版权声明:
本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

相关文章

Django-Import-Export插件关于外键的处理

前言 Django-Import-Export是一款很好用很方便的Django数据导出导入插件,可以和DjangoAdmin管理后台完美集成,只需要少量的代码配置即可方便实现你要的多种格式导出导入,关于这个插件的使用更多可以看我之前的文章:这里放文章链接 之前我在使用中都是专门做了一个原始数据的表来存导入的数据,然后再对原始数据表做一些数据处理,把数据存到其他表才能真正使用这些数据。(不是很好的做

2022-04-02 · Django · 约 1 分钟

Django的信号机制入门

概念 django自带一套信号机制来帮助我们在框架的不同位置之间传递信息。也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者(receivers)。 (感觉就很像Qt的信号与槽机制) 信号系统包含以下三要素: 发送者-信号的发出方 信号-信号本身 接收者-信号的接受者 Django内置了一整套信号,下面是一些比较常用的: 在

2022-08-26 · Django · 约 1 分钟

讨论

共 0 条

良言一句三冬暖,恶语伤人六月寒。

加载评论中…