django 用户模型扩展

对于用户模型,我一直用Django内置的Model,django.contrib.auth.models.User,很方便。但是终究还是比较有限的,因此我对其进行了扩展。

扩展User模型的方法有很多,比较常见的是可以写个类,继承User,如:

class MyUser(User):
    fields .......

但我觉得这样有点太乱的,所有字段都保持在同一个表中,我用了另外一种方法,新建一个数据表,用来保存用户的一些其他信息,例如学校,爱好,自我介绍等等。然后和User建立一对一的关系。代码如下:

GENDER = {
    u'男孩':'boy',
    u'女孩':'girl'
}


class UserProfile(models.Model):
    avator = models.ImageField(upload_to='userimg',blank=True)
    age = models.IntegerField(null=True,blank=True,default=0)
    school = models.CharField(max_length=48,blank=True)
    gender = models.CharField(default='boy',max_length=10,choices=GENDER.items())
    hobby = models.CharField(max_length=255,blank=True)
    user = models.OneToOneField(User,unique=True)
    motto = models.CharField(max_length=255,blank=True)
    self_introduction = models.TextField(blank=True)
    #phone = models.CharField(max_length=13,blank=True)
    birthday = models.DateField(blank=True,default='2000-01-01')

    def __unicode__(self):
        return "{0} profile".format(self.user.username)

接下来是视图类的编写。我写了两个界面,一是用户信息展示界面,另外一个是编辑界面。

PS:其实这不是最理想的方法,应该用ajax实现,且一个界面即可,像知乎那样。但我只是想再多学习一下Django的视图类。

class ChangeUserprofileView(FormView):
    form_class = UserProfileForm
    success_url = '/dashboard/userprofile/'
    template_name = 'dashboard/changeuserprofile.html'

    def form_valid(self, form):
        if self.request.FILES.has_key('avator'):
            form.instance.avator = self.request.FILES['avator']
        form.save()
        return super(ChangeUserprofileView,self).form_valid(form)

    def get_form(self, form_class=None):
        if form_class is None:
            form_class = self.get_form_class()
        profile = UserProfile.objects.get_or_create(user=self.request.user)[0]
        return form_class(instance=profile,**self.get_form_kwargs())

当post数据时,会自动调用form_valid。get_form会自动填充已经存在的实例。

class UserProfileView(DetailView):
    queryset = UserProfile.objects.all()
    context_object_name = 'userprofile'
    template_name = 'dashboard/userprofile.html'

    def get(self, request, *args, **kwargs):
        user = self.request.user
        self.object = UserProfile.objects.get_or_create(user=user)[0]
        context = self.get_context_data(userprofile=self.object)
        context['user'] = self.request.user
        context['publish_article'] = len(Article.objects.filter(author=user))
        return self.render_to_response(context)

这段代码比较简单,就重构一下get方法。

综述:理想方式是使用ajax写。

--------EOF---------
微信分享/微信扫码阅读