如何正确实施 example.com/username 和 example.com/id123?

How to correctly implement both example.com/username and example.com/id123?

我想让用户拥有自定义的 url,例如 example.com/username,但我不想强迫他们这样做,所以在这种情况下,我想要这样的地址:example.com/id123

当前方法:

# root urls.py
urlpatterns = [
   url(r'^((?P<user_id>[i][d]\d+)|(?P<username>[\w.+-]+))/', include('profiles.urls', namespace='profiles_user')),

# profiles/urls.py
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.profiles_home, name='profiles_home'),
]

# profiles/views.py
def profiles_home(request, user_id=None, username=None):
    if user_id:
        user_id = int(user_id.replace('id', ''))
        user = get_object_or_404(UserProfile, pk=user_id)
    else:
        user = get_object_or_404(UserProfile, username=username)
    return render(request, 'profiles/profiles_home.html', {'profile_user': user})

这种方法不灵活。特别是 navigation\menu 的问题,我想在其中制作一个按钮 My page。对于导航,我使用 django-sitetree,其中没有使用 'double'-link 作为 1 个按钮的内置功能,这取决于用户是否有用户名。 sitetree 用于将按钮连接到 link 的方案正在定义 url_namespace:url_name.

谁能告诉我如何 improve/simplify 我的网址?

为了处理导航按钮,我通常将 id=0 映射到当前用户,所以这里是您的视图

def profiles_home(request, user_id=None, username=None):
    if user_id == 0:
       user = request.user
    else if user_id:
        user_id = int(user_id.replace('id', ''))
        user = get_object_or_404(UserProfile, pk=user_id)
    else:
        user = get_object_or_404(UserProfile, username=username)
    return render(request, 'profiles/profiles_home.html', {'profile_user': user})

我向 UserProfile 模型添加了一个新字段 url

url = models.CharField(_('URL address'), max_length=30, unique=True)

其余部分:

# main url
urlpatterns = [
    url(r'^admin/', admin.site.urls),

    # My url
    url(r'^(?P<user_url>[\w.-]+)/', include('profiles.urls', namespace='profiles_username')),
]

# profiles.urls (my app's urls)
from django.conf.urls import url
from . import views

urlpatterns = [
    url(r'^$', views.profiles_home, name='profiles_home'),
]

# profiles.views
def profiles_home(request, user_url):
    user = get_object_or_404(UserProfile, url=user_url)

    return render(request, 'profiles/profiles_home.html', {'user_profile_form': user})

url 在创建用户后生成。因为我使用 AllAuth,所以 Adaptor 看起来像:

from allauth.account.adapter import DefaultAccountAdapter
from allauth.account.utils import user_username, user_email, user_field

class UserProfileAdapter(DefaultAccountAdapter):
    def save_user(self, request, user, form, commit=True):

        data = form.cleaned_data
        first_name = data.get('first_name')
        last_name = data.get('last_name')
        email = data.get('email')
        username = data.get('username')
        user_email(user, email)
        user_username(user, username)

        if first_name:
            user_field(user, 'first_name', first_name)
        if last_name:
            user_field(user, 'last_name', last_name)
        if 'password1' in data:
            user.set_password(data["password1"])
        else:
            user.set_unusable_password()
        self.populate_username(request, user)
        if commit:
            user.save()

        # Add user's url to User's model
        user.url = 'id'+str(user.pk)
        user.save()
        return user

还需要对用户个人资料页面进行验证,以禁止用户使用自定义 url,例如 id123456,即 id+nums,但事实并非如此目前已实施。