在实际的开发中,我们有些操作常常是要记录当前操作的用户的, 比如我在下面的例子中,用户可以自定义话题,那么,所有用户自定义 的话题,就需要记录是哪个用户定义了它,下面我就结合Django自带 的CreateView来记录下今天的Django学习笔记.

首先是models.py

# -*- coding: utf-8 -*-
from django.db import models
from django.core.urlresolvers import reverse
from django.contrib.auth.models import User


class Topic(models.Model):
    title = models.CharField(max_length=200)
    create_time = models.DateTimeField(auto_now_add=True)
    create_user = models.ForeignKey(User)

    def __unicode__(self):
        return self.title

    def get_absolute_url(self):
        return reverse("interaction:detail", args=[self.id])

这里添加get_absolute_url方法,是因为在CreateView创建成功之后, 后重定向到model的get_absolute_url所指向的地址,如果这里不实现该方法, 也是可以的,就需要在CreateView中给出success_url属性, 或实现get_success_url()方法,这三种方式是一样的作用, 就是指定创建成功之后的重定向的位置.

然后是views.py

# -*- coding: utf-8 -*-
from django.views.generic import *
from models import *
from forms import *


class TopicCreateView(CreateView):
    model = Topic
    form_class = TopicForm
    template_name_suffix = '_create_form'

    def get_form_kwargs(self):
        # add request for form to validate
        kwargs = super(TopicCreateView, self).get_form_kwargs()
        kwargs.update({"request": self.request})
        return kwargs

在这里,重写了get_form_kwargs, 是因为在下面的forms.py中,TopicForm需要用到request, 所以这里就把request放到其初始化方法中, 这样就可以在forms.py中获取到当前用户 其中还用到了form_class这个属性,用户指定创建时适用的表单. 这个类我是在forms.py里面定义的,如下:

# -*- coding: utf-8 -*-
from django import forms
import models


class TopicForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        # 这里一定要用pop,而不是get,
        # 因为form的__init__方法并没有"request"这个参数
        self.request = kwargs.pop("request", None)
        super(TopicForm, self).__init__(*args, **kwargs)

    def save(self, commit=True):
        self.instance.create_user = self.request.user
        return super(TopicForm, self).save(commit=True)

    class Meta:
        model = models.Topic
        fields = ['title']

这里的fields,是指定表单里要包含哪些信息, 因为create_time是系统自动在创建时添加的,所以不需要. 而create_user是因为我们要自动添加为当前用户, 所以也不需要,于是就只需要一个title就够了. 这里重写了默认的save方法,就是在这里, 我们把当前用户写入了当前的事例,成功的实现了目的.

接着就是templates了, 因为我们通过template_name_suffix重新定义了其后缀, 所以我们的templates如下,其名字为topic_create_form.html

{% block content %}
    <form action="" method="POST">
        {% csrf_token %}
        {{ form.as_p }}
        <input type="submit" value="Create">
    </form>
{% endblock %}

最后是urls.py

# -*- coding: utf-8 -*-
from django.conf.urls import url
from django.contrib.auth.decorators import login_required
import views

urlpatterns = [
    url(R'^create_topic/$', login_required(views.TopicCreateView.as_view()), name='create_topic'),
]

当然,这一切看上去比较简单,但是实际上从头开始操作还是有比较多的问题, 我也是整理了一个思维导图才搞懂这些View,modelform之间的调用关系, 下面是这个思维导图的一个图片版本:

CreateView.png



blog comments powered by Disqus

Published

24 November 2015

Category

tech_world

Tags