我是Django的新手,但已经完成了一些教程并自己创建了一个非常类似于使用Django演练应用程序rango的Tango的应用程序。
到目前为止,一切都有效,但当我尝试添加注册功能时,链接会将我带到错误的模板。我认为这是因为我从其他应用程序迁移了部分,所以也许网页正在寻找不存在的东西?
这是我的forms.py:
from django import forms
from django.contrib.auth.models import User
from address_book.models import Client, UserProfile
class ClientForm(forms.ModelForm):
name = forms.CharField(max_length=128, help_text="Name: ")
phone = forms.IntegerField(help_text="Phone Number: ")
address = forms.CharField(max_length=128, help_text="Address: ")
desired_weight = forms.IntegerField(help_text="Desired Weight: ")
start_weight = forms.IntegerField(help_text="Start Weight: ")
views = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
likes = forms.IntegerField(widget=forms.HiddenInput(), initial=0)
slug = forms.CharField(widget=forms.HiddenInput(), required=False)
comments = forms.CharField(max_length=500, help_text="Comments: ")
# An inline class to provide additional information on the form.
class Meta:
# Provide an association between the ModelForm and a model
model = Client
fields = ('name', 'phone', 'address', 'desired_weight', 'start_weight',)
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta:
model = User
fields = ('username', 'email', 'password')
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('website', 'picture')
models.py
from django.db import models
from django.template.defaultfilters import slugify
from django.contrib.auth.models import User
class Client(models.Model):
name = models.CharField(max_length=128, unique=True)
phone = models.IntegerField(default=0)
desired_weight = models.IntegerField(default=0)
start_weight = models.IntegerField(default=0)
address = models.CharField(max_length=128, blank=True)
comments = models.CharField(max_length=500, blank=True)
slug = models.SlugField(unique=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Client, self).save(*args, **kwargs)
def __unicode__(self):
return self.name
class UserProfile(models.Model):
# This line is required. Links UserProfile to a User model instance.
user = models.OneToOneField(User)
# The additional attributes we wish to include.
website = models.URLField(blank=True)
picture = models.ImageField(upload_to='profile_images', blank=True)
# Override the __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.user.username
views.py
from django.http import HttpResponse
from django.shortcuts import render
from address_book.forms import ClientForm, UserForm, UserProfileForm
from address_book.models import Client
def index(request):
client_list = Client.objects.all().order_by('name')
# Construct a dictionary to pass to the template engine as its context.
# Note the key boldmessage is the same as {{ boldmessage }} in the template!
context_dict = {'clients': client_list}
# Return a rendered response to send to the client.
# We make use of the shortcut function to make our lives easier.
# Note that the first parameter is the template we wish to use.
return render(request, 'address_book/index.html', context_dict)
def add_client(request):
# A HTTP POST?
if request.method == 'POST':
form = ClientForm(request.POST)
# Have we been provided with a valid form?
if form.is_valid():
# Save the new category to the database.
form.save(commit=True)
# Now call the index() view.
# The user will be shown the homepage.
return index(request)
else:
# The supplied form contained errors - just print them to the terminal.
print form.errors
else:
# If the request was not a POST, display the form to enter details.
form = ClientForm()
# Bad form (or form details), no form supplied...
# Render the form with error messages (if any).
return render(request, 'address_book/add_client.html', {'form': form})
def client(request, client_name_slug):
# Create a context dictionary which we can pass to the template rendering engine.
context_dict = {}
try:
# Can we find a category name slug with the given name?
# If we can't, the .get() method raises a DoesNotExist exception.
# So the .get() method returns one model instance or raises an exception.
client = Client.objects.get(slug=client_name_slug)
context_dict['client_name'] = client.name
context_dict['client_name_slug'] = client_name_slug
context_dict['client_phone'] = client.phone
context_dict['client_address'] = client.address
context_dict['desired_weight'] = client.desired_weight
context_dict['start_weight'] = client.start_weight
context_dict['comments'] = client.comments
# Retrieve all of the associated pages.
# Note that filter returns >= 1 model instance.
# pages = Page.objects.filter(category=category)
# Adds our results list to the template context under name pages.
# context_dict['pages'] = pages
# We also add the category object from the database to the context dictionary.
# We'll use this in the template to verify that the category exists.
context_dict['client'] = client
except Client.DoesNotExist:
# We get here if we didn't find the specified category.
# Don't do anything - the template displays the "no category" message for us.
pass
# Go render the response and return it to the client.
print context_dict
return render(request, 'address_book/client.html', context_dict)
def register(request):
# A boolean value for telling the template whether the registration was successful.
# Set to False initially. Code changes value to True when registration succeeds.
registered = False
# If it's a HTTP POST, we're interested in processing form data.
if request.method == 'POST':
# Attempt to grab information from the raw form information.
# Note that we make use of both UserForm and UserProfileForm.
user_form = UserForm(data=request.POST)
profile_form = UserProfileForm(data=request.POST)
# If the two forms are valid...
if user_form.is_valid() and profile_form.is_valid():
# Save the user's form data to the database.
user = user_form.save()
# Now we hash the password with the set_password method.
# Once hashed, we can update the user object.
user.set_password(user.password)
user.save()
# Now sort out the UserProfile instance.
# Since we need to set the user attribute ourselves, we set commit=False.
# This delays saving the model until we're ready to avoid integrity problems.
profile = profile_form.save(commit=False)
profile.user = user
# Did the user provide a profile picture?
# If so, we need to get it from the input form and put it in the UserProfile model.
if 'picture' in request.FILES:
profile.picture = request.FILES['picture']
# Now we save the UserProfile model instance.
profile.save()
# Update our variable to tell the template registration was successful.
registered = True
# Invalid form or forms - mistakes or something else?
# Print problems to the terminal.
# They'll also be shown to the user.
else:
print user_form.errors, profile_form.errors
# Not a HTTP POST, so we render our form using two ModelForm instances.
# These forms will be blank, ready for user input.
else:
user_form = UserForm()
profile_form = UserProfileForm()
# Render the template depending on the context.
return render(request,
'address_book/register.html',
{'user_form': user_form, 'profile_form': profile_form, 'registered': registered} )
register.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Register{% endblock %}
{% block body_block %}
<h1>Register with 3010 Weightloss !</h1>
{% if registered %}
<a href="/address_book/">Return to the homepage.</a><br />
{% else %}
Rango says: <strong>register here!</strong><br />
<form id="user_form" method="post" action="/address_book/register/"
enctype="multipart/form-data">
{% csrf_token %}
<!-- Display each form. The as_p method wraps each element in a paragraph
(<p>) element. This ensures each element appears on a new line,
making everything look neater. -->
{{ user_form.as_p }}
{{ profile_form.as_p }}
<!-- Provide a button to click to submit the form. -->
<input type="submit" name="submit" value="Register" />
</form>
{% endif %}
{% endblock %}
urls.py
from django.conf.urls import patterns, url
from address_book import views
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^add_client/$', views.add_client, name='add_client'),
url(r'^(?P<client_name_slug>[\w\-]+)/$', views.client, name='client'),
url(r'^register/$', views.register, name = 'register'),
)
的index.html
{% extends 'base.html' %}
{% load staticfiles %}
{% block title %}Index{% endblock %}
{% block body_block %}
<head>
<title>Rango</title>
</head>
<body>
<h2>Current Clients:</h2>
{% for client in clients %}
<li><a href="{% url 'client' client.slug %}">{{ client.name }}</a></li>
{% endfor %}
</body>
{% endblock %}
最后是我的base.html:
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>Address_book</title>
</head>
<body>
{% block body_block %}{% endblock %}
</body>
<h2> Need to make changes? </h2>
<ul>
<li><a href="{% url 'add_client' %}">Add new client</a></li>
<li><a href="/address_book/register/">Register here</a></li>
</ul>
</html>
就像我上面所说,当我点击链接在index.py中注册时,它会将我带到另一个模板client.html。
答案 0 :(得分:2)
看起来问题是/address_book/register/
与您的客户端网址匹配,该网址位于注册网址之前。要解决这个问题,解决这个问题的一种方法是切换URL字符串的顺序:
# urls.py
urlpatterns = patterns('',
url(r'^$', views.index, name='index'),
url(r'^add_client/$', views.add_client, name='add_client'),
url(r'^register/$', views.register, name = 'register'),
url(r'^(?P<client_name_slug>[\w\-]+)/$', views.client, name='client'),
)
但是,最好在base.html中按名称调用网址,而不是依赖网址字符串的顺序:
# base.html
...
<li><a href="{% url 'register' %}">Register here</a></li>
...