我已使用Heroku将我的应用程序推送到生产版本中,并且由于我之前已经登录,因此我以当前用户的身份进入首页,但是如果我注销该应用程序,则会重新呈现该首页, messages.error'用户不存在'。该应用程序可以在https://micro-blog-site.herokuapp.com上找到,其他详细信息可以在下面找到。
编辑:我可以通过管理应用注销,看来登录或注册链接均无效。
这是单击注销时的Heroku日志
2019-05-21T20:45:28.529489+00:00 heroku[router]: at=info method=GET path="/" host=micro-blog-site.herokuapp.com request_id=640f08ae-f865-47ac-bb92-5f3cef07250d fwd="174.115.122.102" dyno=web.1 connect=0ms service=33ms status=200 bytes=2532 protocol=https
2019-05-21T20:45:28.433881+00:00 heroku[router]: at=info method=GET path="/logout" host=micro-blog-site.herokuapp.com request_id=24447334-9a94-4db6-98be-97033077a513 fwd="174.115.122.102" dyno=web.1 connect=0ms service=10ms status=302 bytes=376 protocol=https
2019-05-21T20:45:28.432504+00:00 app[web.1]: True
2019-05-21T20:45:28.435933+00:00 app[web.1]: 10.93.215.14 - - [21/May/2019:16:45:28 -0400] "GET /logout HTTP/1.1" 302 0 "https://micro-blog-site.herokuapp.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.1 Safari/605.1.15"
2019-05-21T20:45:28.531462+00:00 app[web.1]: 10.93.215.14 - - [21/May/2019:16:45:28 -0400] "GET / HTTP/1.1" 200 2077 "https://micro-blog-site.herokuapp.com/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0.1 Safari/605.1.15"
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from django.contrib.auth import login, logout, authenticate
from .forms import CustomUserCreationForm, CustomAuthForm, PostForm
from django.contrib import messages
from .models import Post, User, UserProfile
from datetime import datetime
# Create your views here.
############################################
#
# Homepage view with form to create a post
# and display a feed of post by most recent
# published
#
############################################
def homepage(request):
if request.method == "POST":
form = PostForm(request.POST)
if form.is_valid():
post = form.save(commit=False)
post.user = request.user
post.published = datetime.now()
post.save()
return redirect('micro:homepage')
else:
messages.error(request, "Error!")
form = PostForm()
if request.user.is_authenticated:
return render(request, 'micro/home.html', {"posts":Post.objects.order_by('-published'), "form":form, "following":[following for following in request.user.userprofile.follows.all()]})
else:
return render(request, 'micro/home.html', {"posts":Post.objects.order_by('-published'), "form":form})
###########################################
#
# Register view with a form to register a
# user
#
##########################################
def register(request):
if request.method == "POST":
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save()
UserProfile.objects.create(user=user)
username = form.cleaned_data.get('username')
login(request, user)
messages.success(request, f"New account created: {username}")
return redirect('micro:homepage')
else:
for msg in form.errors:
for message in form.errors[msg]:
messages.error(request, f"{message}")
return render(request, 'micro/register.html', {"form":form})
form = CustomUserCreationForm()
return render(request, 'micro/register.html', {"form":form})
###########################################
#
# Logout request, redirects to homepage
#
###########################################
def logout_request(request):
logout(request)
return redirect('micro:homepage')
###########################################
#
# Login view with a form for a user to
# enter username and password
#
##########################################
def login_request(request):
if request.method == "POST":
form = CustomAuthForm(request, data=request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
user = authenticate(username=username, password=password)
if user is not None:
login(request, user)
messages.info(request, f"You are now logged in as {username}")
return redirect(f'/{user.username}')
else:
messages.error(request, "Invalid username or password")
else:
messages.error(request, "Invalid username or password")
form = CustomAuthForm()
return render(request, 'micro/login.html', {"form":form})
#########################################
#
# Profile view displays the user profile
# of a specified user and their posts
#
#########################################
def profile(request, username):
print(request.user.is_authenticated)
if request.user.is_authenticated:
if username in [user.username for user in User.objects.all()]:
userposts = Post.objects.filter(user__username=username).order_by('-published')
return render(request, 'micro/profile.html', {"userposts":userposts, "username":username})
else:
messages.error(request, "User does not exist")
return redirect('micro:homepage')
else:
messages.error(request, "Login or signup to view this page")
return redirect('micro:homepage')
settings.py
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/2.2/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = 'yd@19!!nf4)-4s9(f=y9ou41s2$6g&(#4(*o!4b-zgkeip(^5-'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = False
ALLOWED_HOSTS = ['micro-blog-site.herokuapp.com','127.0.0.1', '0.0.0.0']
# Allows creation of custom User model
AUTH_USER_MODEL = 'micro.User'
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'micro.apps.MicroConfig',
]
MIDDLEWARE = [
'whitenoise.middleware.WhiteNoiseMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'mysite.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'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',
],
},
},
]
WSGI_APPLICATION = 'mysite.wsgi.application'
# Database
# https://docs.djangoproject.com/en/2.2/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
}
}
# Password validation
# https://docs.djangoproject.com/en/2.2/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Logging
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'console': {
'class': 'logging.StreamHandler',
},
},
'loggers': {
'django': {
'handlers': ['console'],
'level': os.getenv('DJANGO_LOG_LEVEL', 'DEBUG'),
},
},
}
# Internationalization
# https://docs.djangoproject.com/en/2.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'America/Toronto'
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
PROJECT_ROOT = os.path.join(os.path.abspath(__file__))
APP_DIR = os.path.join(BASE_DIR, 'micro')
STATIC_ROOT = os.path.join(APP_DIR, 'staticfiles')
STATIC_URL = '/static/'
# Extra lookup directories for collectstatic to find static files
STATICFILES_DIRS = (
os.path.join(APP_DIR, 'static'),
)
# Add configuration for static files storage using whitenoise
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
import dj_database_url
prod_db = dj_database_url.config(conn_max_age=500)
DATABASES['default'].update(prod_db)
urls.py
from django.contrib import admin
from django.urls import path, include
from . import views
app_name = 'micro'
urlpatterns = [
path('', views.homepage, name="homepage"),
path('register/', views.register, name="register"),
path('logout/', views.logout_request, name="logout"),
path('login/', views.login_request, name="login"),
path('<username>', views.profile, name="profile"),
]
header.html
<head>
{% load static %}
<link href="{% static 'micro/css/materialize.css' %}" rel="stylesheet">
<link href="{% static 'micro/css/styles.css' %}" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Titillium+Web" rel="stylesheet">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="{% static 'micro/js/materialize.js' %}"></script>
<!-- <script src="{% static 'micro/js/jquery.js' %}"></script>-->
</head>
<body class="green lighten-5">
{% include 'micro/includes/nav.html' %}
<br>
{% include 'micro/includes/messages.html' %}
<div class="container">
<br>
{% block content %}
{% endblock %}
</div>
</body>
nav.html
<nav class="green lighten-3">
<div class="nav-wrapper">
<a href="/" class="brand-logo" style="padding-left: 15px;">Logo</a>
<ul id="nav-mobile" class="right hide-on-med-and-down">
{% if user.is_authenticated %}
<li><a href="{{user.username}}">{{user.username|title}}</a></li>
<li><a href="/logout">Logout</a></li>
{% else %}
<li><a href="/login">Login</a></li>
<li><a href="/register">Register</a></li>
{% endif %}
</ul>
</div>
</nav>
home.html
{% extends 'micro/header.html' %}
{% block content %}
<div class="row">
{% if request.user.is_authenticated %}
<div class="col l4 m8 offset-m2 s12 center-align">
<h2>Welcome {{user.username}}!</h2>
{% include 'micro/includes/post-form.html' %}
</div>
<div class="col l7 offset-l1 m8 offset-m2 s12 center-align">
<h2>This is your feed</h2><br>
{% include 'micro/includes/feed.html' %}
</div>
{% else %}
<div class="col m6 offset-m3 s12 center-align">
<h3>Welcome!</h3>
<a href="/login" class="col s4 offset-s1 waves-effect waves-light btn green lighten-2">Login</a>
<p class="col s2"><strong>or</strong></p>
<a href="/register" class="col s4 waves-effect waves-light btn green lighten-2">Register</a>
</div>
{% endif %}
</div>
</div>
{% endblock %}