URL中的Django(?P <pk> \ d +)部分工作

时间:2017-09-09 05:29:42

标签: python django django-urls

我将此作为用户app urls.py:

from django.conf.urls import url
from users import views

app_name = 'users'

urlpatterns = [
    url(r'^$',views.UserListView.as_view(),name='user_list'),
    url(r'^(?P<pk>\d+)/$',views.UserProfileView.as_view(),name='user_profile'),
    url(r'^(?P<pk>\d+)/edit$',views.UserEditProfileView.as_view(),name='user-profile-edit'),
    url(r'^login/$',views.user_login,name='user_login'),
    url(r'^logout/$',views.user_logout,name='user_logout'),
    url(r'^register/$',views.register,name='register'),
]

此网址格式url(r'^(?P<pk>\d+)/$',views.UserProfileView.as_view(),name='user_profile'),

适用于此网址http://127.0.0.1:8000/user/1/

但是当我创建一个新用户(用户2)并登录时,当我点击带有该模式的按钮时,我得到一个page not found (404)

这不是错误,但这是它告诉我的:

Page not found (404)
Request Method: GET
Request URL:    http://127.0.0.1:8000/user/3/
Raised by:  users.views.UserProfileView
No user profile info found matching the query
You're seeing this error because you have DEBUG = True in your Django settings file. Change that to False, and Django will display a standard 404 page.

所以基本上,pk 3用户的个人资料是http://127.0.0.1:8000/user/2/而不是http://127.0.0.1:8000/user/3/(反过来,不太确定)。

此处还有我的项目网址:

from django.conf.urls import url
from django.contrib import admin
from django.conf.urls import include
from users import views
from feed import views
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$',views.HomeView.as_view(),name='index'),
    url(r'^user/',include('users.urls',namespace='users')),
    url(r'^feed/',include('feed.urls',namespace='feed')),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

用户app views.py:

from django.shortcuts import render,get_object_or_404
from users.forms import UserForm,UserProfileForm
from users.models import UserProfileInfo
from feed.models import UserPost

from django.contrib.auth.models import User

from django.contrib.auth import authenticate,login,logout
from django.http import HttpResponseRedirect, HttpResponse
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required

from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import (TemplateView,ListView,
                                    DetailView,CreateView,
                                    UpdateView,DeleteView)

# Create your views here.
def user_login(request):
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        user = authenticate(username=username,password=password)

        if user:
            if user.is_active:
                login(request,user)
                return HttpResponseRedirect(reverse('index'))
            else:
                return HttpResponse("Account now active")

        else:
            print("Login Unsuccessful")
            return HttpResponse("Username and/or password are not correct")

    else:
        return render(request,'login.html',{})

def register(request):
    registered = False

    if request.method == 'POST':
        user_form = UserForm(data=request.POST)
        profile_form = UserProfileForm(data=request.POST)

        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save()
            user.set_password(user.password)
            user.save()

            profile = profile_form.save(commit=False)
            profile.user = user

            if 'profile_pic' in request.FILES:
                profile.profile_pic = request.FILES['profile_pic']

            profile.save()
            registered = True
        else:
            print(user_form.errors,profile_form.errors)
    else:
        user_form = UserForm()
        profile_form = UserProfileForm()

    return render(request,'register.html',{
                                        'user_form':user_form,
                                        'profile_form':profile_form,
                                        'registered':registered
                                        })

@login_required
def user_logout(request):
    logout(request)
    return HttpResponseRedirect(reverse('index'))

class UserListView(ListView):
    model = UserProfileInfo
    ordering = ['-join_date']

    def get_context_data(self, **kwargs):
        context = super(UserListView, self).get_context_data(**kwargs)
        context['user_list'] = User.objects.all()
        return context

class UserProfileView(DetailView):
    model = UserProfileInfo
    template = 'users/userprofile.html'

    def get_context_data(self, **kwargs):
        context = super(UserProfileView, self).get_context_data(**kwargs)
        context['user_post'] = UserPost.objects.all()
        return context

class UserEditProfileView(LoginRequiredMixin,UpdateView):
    login_url = '/login/'
    redirect_field_name = '/users_detail.html'
    form_class = UserProfileForm
    model = UserProfileInfo

用户app models.py:

from django.db import models
from django.utils import timezone
from django.contrib.auth.models import User
from users.choices import *

# Create your models here.
class UserProfileInfo(models.Model):
    user = models.OneToOneField(User)

    first_name = models.CharField(max_length=50,default='User')
    join_date = models.DateTimeField(default=timezone.now)
    profile_pic = models.ImageField(upload_to='profile_pics',blank=True)
    location = models.CharField(max_length=150)
    title = models.CharField(max_length=250)
    user_type = models.IntegerField(choices=USER_TYPE_CHOICES,default=1)
    website = models.URLField(max_length=100,blank=True)
    about = models.TextField(max_length=500,default='about')
    twitter = models.CharField(max_length=50,blank=True)
    dribbble = models.CharField(max_length=50,blank=True)
    github = models.CharField(max_length=50,blank=True)

    def __str__(self):
        return self.user.username

更新:

新用户app models.py:

class UserProfile(models.Model):
    user = models.OneToOneField(User)

    first_name = models.CharField(max_length=50,default='User')
    join_date = models.DateTimeField(default=timezone.now)
    profile_pic = models.ImageField(upload_to='profile_pics',blank=True)
    location = models.CharField(max_length=150)
    title = models.CharField(max_length=250)
    user_type = models.IntegerField(choices=USER_TYPE_CHOICES,default=1)
    website = models.URLField(max_length=100,blank=True)
    about = models.TextField(max_length=500,default='about')
    twitter = models.CharField(max_length=50,blank=True)
    dribbble = models.CharField(max_length=50,blank=True)
    github = models.CharField(max_length=50,blank=True)

    @receiver(post_save, sender=User)
    def create_user_profile(sender, instance, created, **kwargs):
        if created:
            UserProfile.objects.create(user=instance)

    @receiver(post_save, sender=User)
    def save_user_profile(sender, instance, **kwargs):
        instance.userprofile.save()

    def __str__(self):
        return self.user.username

新错误:

IntegrityError at /user/register/
UNIQUE constraint failed: users_userprofile.user_id

错误追溯:

Traceback (most recent call last):
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return Database.Cursor.execute(self, query, params)
sqlite3.IntegrityError: UNIQUE constraint failed: users_userprofile.user_id

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/handlers/exception.py", line 41, in inner
    response = get_response(request)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/handlers/base.py", line 187, in _get_response
    response = self.process_exception_by_middleware(e, request)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/core/handlers/base.py", line 185, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/Users/garrettlove/Desktop/evverest/users/views.py", line 58, in register
    profile.save()
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/base.py", line 807, in save
    force_update=force_update, update_fields=update_fields)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/base.py", line 837, in save_base
    updated = self._save_table(raw, cls, force_insert, force_update, using, update_fields)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/base.py", line 923, in _save_table
    result = self._do_insert(cls._base_manager, using, fields, update_pk, raw)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/base.py", line 962, in _do_insert
    using=using, raw=raw)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/query.py", line 1076, in _insert
    return query.get_compiler(using=using).execute_sql(return_id)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/models/sql/compiler.py", line 1099, in execute_sql
    cursor.execute(sql, params)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/backends/utils.py", line 80, in execute
    return super(CursorDebugWrapper, self).execute(sql, params)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/utils.py", line 94, in __exit__
    six.reraise(dj_exc_type, dj_exc_value, traceback)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/utils/six.py", line 685, in reraise
    raise value.with_traceback(tb)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/backends/utils.py", line 65, in execute
    return self.cursor.execute(sql, params)
  File "/anaconda/envs/test/lib/python3.6/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
    return Database.Cursor.execute(self, query, params)
django.db.utils.IntegrityError: UNIQUE constraint failed: users_userprofile.user_id

3 个答案:

答案 0 :(得分:1)

您的urls.py错了。当您拨打http://127.0.0.1:8000/user/3/时,它会调用视图users.views.UserProfileView,并且此UserProfileView未获得您需要传递userID的任何urls.py

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^$',views.HomeView.as_view(),name='index'),
    url(r'^user/(?P<pk>\d+)/',include('users.urls',namespace='users')),
    url(r'^feed/',include('feed.urls',namespace='feed')),
]

答案 1 :(得分:1)

你所做的一切都是正确的。但错误是自我解释。与UserProfileInfo模型相关的User 一对一。所以一旦你创建了一个新用户。将创建一个新的userprofileinfo,但不会自动创建。因此它给出了错误。

  

每当创建新用户时,您都需要发送信号以创建新的userprofileinfo。

from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver


class UserProfile(models.Model):
    user = models.OneToOneField(User)

    first_name = models.CharField(max_length=50,default='User')
    . . . . . . . . 
    . . . . . . . .

    def __str__(self):
        return self.user.username

@receiver(post_save, sender=User)
def create_user_profile(sender, instance, created, **kwargs):
    if created:
        UserProfile.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_profile(sender, instance, **kwargs):
    instance.userprofile.save()

最后,我更改了模型名称,因此请相应更改。现在,它将完美地运作。

答案 2 :(得分:0)

不应该是网址:

url(r'^user/(?P<pk>\d+)/$', views.UserProfileView.as_view(), name='user_profile'),