python 编程入门到实践 第19章-用户账户

一、添加新主题

建立表单,在models.py所在文件目录建立forms.py文件;

from django import forms

from .models import Topic, Entry

class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        fields = ['text']
        labels = {'text': ''}

建立表单的目地是为了让用户能够输入新的主题信息,因此,需要为这项功能建立新的URL地址,在learning_logs/urls.py文件中输入如下内容:

from django.urls import path,include
from . import views
# from django.conf.urls import url

app_name = 'learning_logs'

urlpatterns =[#主页
    path('',views.index, name='index'),
    #显示所有主题
    path('topics/',views.topics,name='topics'),
    #特定主题的详细页面
    path("topics/(?p<topic_id>\d+)/",views.topic, name='topic'),
    # 用于添加新主题网页
    path("new_topic/",views.new_topic,name='new_topic'),
]

在views.py中建立new_topic函数,与path想对应,代码如下,注意这里与书中不同了:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urlresolvers import reverse

from .models import Topic
from .forms import TopicForm

def index(request):
    """The home page for Learning Log."""
    return render(request, 'learning_logs/index.html')

def topics(request):
    """Show all topics."""
    topics = Topic.objects.filter(owner=request.user).order_by('date_added')
    context = {'topics': topics}
    return render(request, 'learning_logs/topics.html', context)

def topic(request, topic_id):
    """Show a single topic, and all its entries."""
    topic = Topic.objects.get(id=topic_id)
    # Make sure the topic belongs to the current user.
    if topic.owner != request.user:
        raise Http404
        
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic': topic, 'entries': entries}
    return render(request, 'learning_logs/topic.html', context)

def new_topic(request):
    """Add a new topic."""
    if request.method != 'POST':
        # No data submitted; create a blank form.
        form = TopicForm()
    else:
        # POST data submitted; process data.
        form = TopicForm(request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            return HttpResponseRedirect(reverse('learning_logs:topics'))

    context = {'form': form}
    return render(request, 'learning_logs/new_topic.html', context)

创建new_topic.html 模板

{% extends "learning_logs/base.html" %}

{% block content %}
  <h2>Add a new topic:</h2>


  <form action="{% url 'learning_logs:new_topic' %}" method='post'>
    {% csrf_token %}
    {{form.as_p}}

    {% buttons %}
      <button name="submit">add topic</button>
    {% endbuttons %}
  </form>
    
{% endblock content %}

链接到new_topic页面,在topics中添加一个页面new_topic的链接:

topics.html模板如下:

{% block content %}

  <p>Topics</p>

  <ul>
    {% for topic in topics %}
      <li>
        <h3>
        <a href="{% url 'learning_logs:topic' topic.id %}">{{ topic }}</a>
        </h3>
	  </li>
    {% empty %}
      <li>No topics have been added yet.</li>
    {% endfor %}
  </ul>
  
  <h3><a href="{% url 'learning_logs:new_topic' %}">Add a new topic:</a></h3>

{% endblock content %}

19.1.2 添加新条目

用于添加新条目的表单,创建一个与模型Entry相关联的表单,forms.py如下:

from django import forms

from .models import Topic, Entry

class TopicForm(forms.ModelForm):
    class Meta:
        model = Topic
        fields = ['text']
        labels = {'text': ''}

class EntryForm(forms.ModelForm):
    class Meta:
        model = Entry
        fields = ['text']
        labels = {'text': ''}
        widgets = {'text': forms.Textarea(attrs={'cols': 80})}

相应的urls当中,添加与之对应的地址:

from django.urls import path,include
from . import views
# from django.conf.urls import url

app_name = 'learning_logs'

urlpatterns =[#主页
    path('',views.index, name='index'),
    #显示所有主题
    path('topics/',views.topics,name='topics'),
    #特定主题的详细页面
    path("topics/(?p<topic_id>\d+)/",views.topic, name='topic'),
    # 用于添加新主题网页
    path("new_topic/",views.new_topic,name='new_topic'),
    # 用于添加新条目
    path("new_entry/(?p<topic_id>\d+)/", views.new_entry,name='new_entry'),


]

同时,要是在视图当中添加相应窗口,views.py代码如下:

from django.shortcuts import render
from django.http import HttpResponseRedirect, Http404
from django.urls import reverse
from .forms import TopicForm,EntryForm
from .models import Topic, Entry


# Create your views here.

def index(request):
    return render(request,'learning_logs/index.html')


def topics(request):
    topics =Topic.objects.filter(owner=request.user).order_by('date_added')
    # topics =Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)


def topic(request,topic_id):
    topic=Topic.objects.get(id=topic_id)
    if topic.owner != request.user:
        raise Http404
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic':topic,'entries':entries}
    return render(request,'learning_logs/topic.html',context)


def new_topic(request):
    if request.method !='POST':
        form = TopicForm()
    else:
        form = TopicForm(request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            # form.save()
            return(HttpResponseRedirect(reverse('learning_logs:topics')))

    context = {'form':form}
    return render(request,'learning_logs/new_topic.html',context)


def new_entry(request,topic_id):
    """在特定的主题中添加新条目"""
    topic = Topic.objects.get(id=topic_id)
    if request.method != 'POST':
        # 未提交数据创建一个空表单
        form = EntryForm()
    else:
        # POST提交的数据对数据进行处理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
    context={'topic':topic,'form':form}
    return render(request, 'learning_logs/new_entry.html',context)

创建模板new_entry.html

{% extends "learning_logs/base.html" %}
{% block content %}

<p><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></p>
<p>Add a new entry:</p>
<form action="{%url 'learning_logs:new_entry' topic.id %}" method="post">
    {%csrf_token%}
    {{ form.as_p}}
    <button name="submit">add entry</button>

</form>

{% endblock content%}

在特定主题页面增加new_entry的链接(属于前端HTML内容)

topic.html内容如下:

{% extends 'learning_logs/base.html' %}

{% block content %}

  <p>Topic: {{ topic }}</p>

  <p>Entries:</p>
  <p>
      <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
  </p>
{% endblock content %}

19.1.3 创建一个条目,让用户能够编辑既有条目。

urls.py 文件代码如下:

from django.urls import path,include
from . import views
# from django.conf.urls import url

app_name = 'learning_logs'

urlpatterns =[#主页
    path('',views.index, name='index'),
    #显示所有主题
    path('topics/',views.topics,name='topics'),
    #特定主题的详细页面
    path("topics/(?p<topic_id>\d+)/",views.topic, name='topic'),
    # 用于添加新主题网页
    path("new_topic/",views.new_topic,name='new_topic'),
    # 用于添加新条目
    path("new_entry/(?p<topic_id>\d+)/", views.new_entry,name='new_entry'),
    # 编辑条目
    path("edit_entry/(?p<entry_id>\d+))",views.edit_entry, name='edit_entry'),

   
]

views.py文件代码如下:

from django.shortcuts import render
from django.http import HttpResponseRedirect, Http404
from django.urls import reverse
from .forms import TopicForm,EntryForm
from django.contrib.auth.decorators import login_required

from .models import Topic, Entry
# Create your views here.

def index(request):
    return render(request,'learning_logs/index.html')


def topics(request):
    topics =Topic.objects.filter(owner=request.user).order_by('date_added')
    # topics =Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)

def topic(request,topic_id):
    topic=Topic.objects.get(id=topic_id)
    if topic.owner != request.user:
        raise Http404
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic':topic,'entries':entries}
    return render(request,'learning_logs/topic.html',context)

def new_topic(request):
    if request.method !='POST':
        form = TopicForm()
    else:
        form = TopicForm(request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            # form.save()
            return(HttpResponseRedirect(reverse('learning_logs:topics')))

    context = {'form':form}
    return render(request,'learning_logs/new_topic.html',context)


def new_entry(request,topic_id):
    """在特定的主题中添加新条目"""
    topic = Topic.objects.get(id=topic_id)
    if request.method != 'POST':
        # 未提交数据创建一个空表单
        form = EntryForm()
    else:
        # POST提交的数据对数据进行处理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
    context={'topic':topic,'form':form}
    return render(request, 'learning_logs/new_entry.html',context)

这里有一个语句与书中不同:

from django.urls import reverse  #如果你用的是django 2.0以上版本,这条语句是对的

模板new_entry.html代码如下:

{% extends "learning_logs/base.html" %}
{% block content %}

<p><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a></p>
<p>Add a new entry:</p>
<form action="{%url 'learning_logs:new_entry' topic.id %}" method="post">
    {%csrf_token%}
    {{ form.as_p}}
    <button name="submit">add entry</button>

</form>

{% endblock content%}

在topic主题当中添加new_entry,topic.html代码如下:

{%extends 'learning_logs/base.html' %}
{% block header %}
  <h2>{{ topic}}</h2>
{% endblock header %}



{%block content%}

<body>Topic:{{topic}}</body>
<p>Entries:</p>
<p>
    <a href="{%url 'learning_logs:new_entry' topic.id%}">add new entry</a>
</p>
<ul>

{%endblock content%}

19.1.3 编辑条目

首先在URL里面添加链接,learning_logs/urls.py 代码如下:

from django.urls import path,include
from . import views
# from django.conf.urls import url

app_name = 'learning_logs'

urlpatterns =[#主页
    path('',views.index, name='index'),
    #显示所有主题
    path('topics/',views.topics,name='topics'),
    #特定主题的详细页面
    path("topics/(?p<topic_id>\d+)/",views.topic, name='topic'),
    # 用于添加新主题网页
    path("new_topic/",views.new_topic,name='new_topic'),
    # 用于添加新条目
    path("new_entry/(?p<topic_id>\d+)/", views.new_entry,name='new_entry'),
    # 编辑条目
    path("edit_entry/(?p<entry_id>\d+))",views.edit_entry, name='edit_entry'),

   
]

相应的views.py代码如下:

rom django.shortcuts import render
from django.http import HttpResponseRedirect, Http404
from django.urls import reverse
from .forms import TopicForm,EntryForm
from django.contrib.auth.decorators import login_required

from .models import Topic, Entry
# Create your views here.

def index(request):
    return render(request,'learning_logs/index.html')


def topics(request):
    topics =Topic.objects.filter(owner=request.user).order_by('date_added')
    # topics =Topic.objects.order_by('date_added')
    context = {'topics':topics}
    return render(request,'learning_logs/topics.html',context)
@login_required
def topic(request,topic_id):
    topic=Topic.objects.get(id=topic_id)
    if topic.owner != request.user:
        raise Http404
    entries = topic.entry_set.order_by('-date_added')
    context = {'topic':topic,'entries':entries}
    return render(request,'learning_logs/topic.html',context)
@login_required
def new_topic(request):
    if request.method !='POST':
        form = TopicForm()
    else:
        form = TopicForm(request.POST)
        if form.is_valid():
            new_topic = form.save(commit=False)
            new_topic.owner = request.user
            new_topic.save()
            # form.save()
            return(HttpResponseRedirect(reverse('learning_logs:topics')))

    context = {'form':form}
    return render(request,'learning_logs/new_topic.html',context)


def new_entry(request,topic_id):
    """在特定的主题中添加新条目"""
    topic = Topic.objects.get(id=topic_id)
    if request.method != 'POST':
        # 未提交数据创建一个空表单
        form = EntryForm()
    else:
        # POST提交的数据对数据进行处理
        form = EntryForm(data=request.POST)
        if form.is_valid():
            new_entry = form.save(commit=False)
            new_entry.topic = topic
            new_entry.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))
    context={'topic':topic,'form':form}
    return render(request, 'learning_logs/new_entry.html',context)

def edit_entry(request,entry_id):
    entry=Entry.objects.get(id=entry_id)
    topic = entry.topic

    if topic.owner != request.user:
        raise Http404

    if request.method != 'POST':
        form = EntryForm(instance=entry,data=request.POST)
    else:
        form=EntryForm(instance=entry,data=request.POST)
        if form.is_valid():
            form.save()
            return HttpResponseRedirect(reverse('learning_logs:topic',args=[topic.id]))

    context = {'entry':entry, 'topic':topic,'form':form}

    return render(request,'learning_logs/edit_entry.html',context)

模板edit_entry.html代码如下:

{% extends "learning_logs/base.html" %}
{% block content %}

  <p><a href="{% url 'learning_logs:topic' topic.id %}">{{topic}}</a> </p>
  <p>Edit entry:</p>

  <form action="{%url 'learning_logs:edit_entry' entry.id %}" method="post">
      {% csrf_token %}
      {{ form.as_p}}
      <button name="submit">save changes</button>
  </form>
{% endblock content%}

在特定的主题页面中添加edit_entry链接!topic.html代码如下:

{% extends 'learning_logs/base.html' %}

{% block content %}

  <p>Topic: {{ topic }}</p>

  <p>Entries:</p>
  <p>
      <a href="{% url 'learning_logs:new_entry' topic.id %}">add new entry</a>
  </p>
  <ul>
  {% for entry in entries %}
    <li>
      <p>{{ entry.date_added|date:'M d, Y H:i' }}</p>
      <p>{{ entry.text|linebreaks }}</p>
      <p>
        <a href="{% url 'learning_logs:edit_entry' entry.id %}">edit entry</a>
      </p>
    </li>
  {% empty %}
    <li>
      There are no entries for this topic yet.
    </li>
  {% endfor %}
  </ul>

{% endblock content %}

19.2 创建用户账户

19.2.1 创建程序users

python manage.py startapp users

在settings.py文件中添加app 

INSTALLED_APPS = [
    'users',
    'learning_logs',
    'bootstrap3',
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
]

在根目录的urls.py中添加url链接

from django.contrib import admin
from django.urls import path, include
from django.conf.urls import url


urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('learning_logs.urls',namespace='learning_logs')),
    path('users/',include('users.urls',namespace='users')),
]
app_name = 'learning_logs'

由此可以看出,所有应用的URL都应在根目录里面注册。

在users文件夹内,新建urls.py文件

from django.urls import path, include
from django.contrib.auth.views import LoginView
from .import views
from django.conf.urls import url
from django.urls import path, re_path


LoginView.template_name = 'login.html'
urlpatterns=[
   
    re_path('login/',LoginView.as_view(template_name='login.html'),name='login'),
   
    #re_path('logout/',LoginView.as_view(template_name='login.html'),name='logout'),
    #re_path('register/',views.register,name='register'),
]

app_name = 'users'

注意:这里与书中代码不同,还是django版本的问题。另外,这里用的是re_path,你也可以用path

在users文件夹内建立templates文件夹,建立login模板,login.html代码如下:

{% extends "learning_logs/base.html" %}

{% block content %}

  {% if form.errors %}
  <p>Your username and password didn't match. Please try again.</p>
  {% endif %}
    
  <form method="post" action="{% url 'users:login' %}">
  {% csrf_token %}
  {{ form.as_p }}
    
  <button name="submit">log in</button>
  <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
  </form>
    
{% endblock content %}

(PS:这里面尤其要注意的一点是‘users:login’),这里是表示将实参设置为登录页面的URL,因此,大家注意‘login‘ 前后不能有任何空格,小编我就是多加了一个空格,结果死活就是找不到模板,也是醉了!

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a> -
  <a href="{% url 'learning_logs:topics' %}">Topics</a> - 
  {% if user.is_authenticated %}
    Hello, {{ user.username }}.
    
  {% else %}
    <a href="{% url 'users:login' %}">log in</a>
  {% endif %}
</p>

{% block content %}{% endblock %}

19.2.3 注销

修改users/urls.py文件,代码如下:

from django.urls import path, include
from django.contrib.auth.views import LoginView
from .import views

from django.conf.urls import url
from django.urls import path, re_path
# from django.contrib.auth.views import login







LoginView.template_name = 'login.html'
urlpatterns=[
    # url(r'^login/',LoginView.as_view(template_name='users/login.html'),name='login')
    re_path('login/',LoginView.as_view(template_name='login.html'),name='login'),
    # path('login/',LoginView.as_view(template_name='users/login.html'),name="login"),
    re_path('logout/',LoginView.as_view(template_name='login.html'),name='logout'),
]

app_name = 'users'

这里还是,path与re_path都可以。

相应的,要在views.py中重新定义视图users/views.py,代码如下:


from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth import  logout


def logout_view(request):
    """Log the user out."""
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))

在base.html中添加链接:

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a> -
  <a href="{% url 'learning_logs:topics' %}">Topics</a> - 
  {% if user.is_authenticated %}
    Hello, {{ user.username }}.
    <a href="{% url 'users:logout' %}">log out</a>

</p>
--snip
{% block content %}{% endblock %}

19.2.4 注册页面

还是在users/urls.py中增加URL链接

from django.urls import path, include
from django.contrib.auth.views import LoginView
from .import views

from django.conf.urls import url
from django.urls import path, re_path
# from django.contrib.auth.views import login







LoginView.template_name = 'login.html'
urlpatterns=[
   
    re_path('login/',LoginView.as_view(template_name='login.html'),name='login'),
    
    re_path('logout/',LoginView.as_view(template_name='login.html'),name='logout'),
    re_path('register/',views.register,name='register'),
]

app_name = 'users

然后在users/views.py中增加视图,views.py代码如下:

from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login,logout,authenticate
from django.contrib.auth.forms import UserChangeForm

def logout_view(request):
    logout(request)
    return HttpResponseRedirect(reverse('learning_logs:index'))

def register(request):
    if request.method != 'POST':
        form = UserCreationForm()

    else:
        form = UserCreationForm(data=request.POST)

    if form.is_valid():
        new_user = form.save()

        authenticated_user = authenticate(username=new_user.username,password=request.POST['password1'])
        login(request,authenticated_user)

        return HttpResponseRedirect(reverse(('learning_logs:index')))

    context = {'form' : form}
    return render(request,'register.html',context)

这里面要记住一下几点:1、from django.urls import reverse #与书中不同

2、return render(request,'register.html',context) # register.html 路径的问题比较头疼,路径不对容易找不到模板,因此有两种方法,一是增加OS模块(这个比较复杂),二是比较简单一点的,在setting.py文件中增加模板路径,代码如下:

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR,'templates','users')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

大家主要看这段'DIRS': [os.path.join(BASE_DIR,'templates','users')], 反正我是小白,我也不知道这段具体是什么意思,大家有兴趣可以找一下,其实我们对于django的框架还需要在仔细阅读一下,非计算机专业真的很难懂这些东西!

最后是注册模板,register.html代码如下:

{% extends "learning_logs/base.html" %}

{% block content %}

  <form method="post" action="{% url 'users:register' %}">
    {% csrf_token %}
    {{ form.as_p }}

    <button name="submit">register</button>
    <input type="hidden" name="next" value="{% url 'learning_logs:index' %}" />
  </form>

{% endblock content %}

最后,在基础模板中增加链接,代码如下,base.html

<p>
  <a href="{% url 'learning_logs:index' %}">Learning Log</a> -
  <a href="{% url 'learning_logs:topics' %}">Topics</a> - 
  {% if user.is_authenticated %}
    Hello, {{ user.username }}.
    <a href="{% url 'users:logout' %}">log out</a>
  {% else %}
    <a href="{% url 'users:register' %}">register</a> -
    <a href="{% url 'users:login' %}">log in</a>
  {% endif %}
</p>

{% block content %}{% endblock %}

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值