https://www.pythoneatstail.com/en/overview-all-articles/social-accounts-login-using-allauth/

 

Social account signup and login with allauth in Django - PythonEa

The default behavior of the social account signup is that allauth tries to log the user in after the connection to the social account has been made. This is something you may not want, when you want the user to fill in some required fields that the social

www.pythoneatstail.com

 

STATICFILES_DIRS = [
    os.path.join(PROJECT_DIR, 'static'),
    os.path.join(BASE_DIR, 'userauth/static/userauth/'),
]

Static File 위치 추가

 

 

SOCIALACCOUNT_AUTO_SIGNUP = False

Social 로그인 이후에 바로 가입 방지 (추가 정보 필요할 때 사용한다.)

 

@user_router.get('/{user_id}', response={200: schema.UserSchema, 404: schema.ErrorSchema})
def user(request, user_id: int):
	...
    
@user_router.put('/{user_nickname}', response={200: schema.UserProfileSchema, 404: schema.ErrorSchema})
def change_user(request, user_id: int, data: schema.UserProfileSchema):
	...

여기 2개의 Method가 있다. 사용방법에는 전혀 이상이 없지만 밑에 put 메소드를 실행하면 Method Not Allowed 오류가 발생한다. header를 살펴보면 분명히 PUT Method로 보냈는데 GET Method가 실행된다. 첫번째 GET Method가 실행되는 것이다. (맨 위에 것으로 인식한다.)

 

왜 이런 문제가 발생할까? 문제는 Django Resolver의 문제이다. url pattern이 같으면 같게 인식하는 문제이다. 

 

그렇다면 해결을 어떻게 해야할까?

 

방법이 있다. 

 

@user_router.get('/{user_id}', response={200: schema.UserSchema, 404: schema.ErrorSchema})
def user(request, user_id: int):
    
@user_router.put('/{user_nickname}/update', response={200: schema.UserProfileSchema, 404: schema.ErrorSchema})
def change_user(request, user_id: int, data: schema.UserProfileSchema):

위와 같이 url pattern을 다르게 주는 것이다. 하지만 이 방법은 api 규칙에는 맞지 않다. 

 

올바른 방법은 

@user_router.get('/{user_id}', response={200: schema.UserSchema, 404: schema.ErrorSchema})
def user(request, user_id: int):
    
@user_router.put('/{user_id}', response={200: schema.UserProfileSchema, 404: schema.ErrorSchema})
def change_user(request, user_id: int, data: schema.UserProfileSchema):

애초에 파라미터 값을 같게 주는 것이다. 

'Back-End > Django-ninja' 카테고리의 다른 글

Django Ninja Router  (0) 2021.12.07
Django Ninja Render  (0) 2021.11.30
Django Ninja Tutorial 5  (0) 2021.11.30
Django Ninja Tutorial 4  (0) 2021.11.30
Django Ninja Tutorial 3  (0) 2021.11.29

https://www.pythoneatstail.com/en/overview-all-articles/allowing-users-update-and-delete-their-profile/

 

Allowing users to update and delete their profile - PythonEatsTai

Just submitting the form is enough, Django does the rest. For update.html, the relevant part of the template is (shown in part):

www.pythoneatstail.com

 

 

Wagtail 방법이라기보단 Django에서 allauth를 사용하는 방법이다. 어차피 Wagtail도 Django 기반이니 상관 없을 것 같다. 

 

 

1. forms.py

from django.forms import ModelForm

class CustomUserUpdateForm(ModelForm):
    class Meta:
        model = CustomUser
        fields = ['first_name', 'last_name', 'display_name', 'date_of_birth', 'address1', 'address2', 'zip_code', 'city', 'country', 'mobile_phone', 'additional_information', 'photo',]
        widgets = {'date_of_birth': forms.DateInput(attrs={'type':'date'})}

User 정보의 update를 위해서 Django ModelForm을 사용한다. 

 

 

2. views.py

from django.views.generic.edit import UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import CustomUser
from .forms import CustomUserUpdateForm

class CustomUserUpdateView(UpdateView):
    model = CustomUser
    form_class = CustomUserUpdateForm


class CustomUserDeleteView(DeleteView):
    model = CustomUser
    success_url = reverse_lazy('account_signup')

Django에서 제공하는 Update, DeleteView를 사용한다. 

 

파이썬의 클래스들은 import 시에 바로 호출이 된다.
따라서
reverse 는 fbv에서 사용이 된다.
reverse_lazy는 주로 cbv에서 success_url을 사용할 경우 사용이 된다.

 

 

3. urls.py

path('<int:pk>/update/', CustomUserUpdateView.as_view(template_name='account/update.html'), name='account_update'),
path('<int:pk>/delete/', CustomUserDeleteView.as_view(template_name='account/delete.html'), name='account_delete'),

 

 

4. delete.html

<form method="post">
    {% csrf_token %}
    <p>{% trans "Are you sure you want to delete the account" %} {{ object.email }}?</p>
    <button type="submit" class="btn btn-danger">{% trans "Delete" %}</button>
</form>

https://www.pythoneatstail.com/en/overview-all-articles/signup-and-password-reset-email-verification-allauth-django/

 

Signup and password reset with allauth's email verification in Django

This tells allauth that we want to authenticate via email, that an email field is required, that we also want to verify our email address by sending a verification link and that we will not use the username. Behind the scenes Django will still use a unique

www.pythoneatstail.com

 

 

1. base.py

ACCOUNT_AUTHENTICATION_METHOD = 'email'
ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_EMAIL_VERIFICATION = 'mandatory'
ACCOUNT_USERNAME_REQUIRED = False

인증 수단으로 username대신 email을 사용해야한다. 

 

 

2. local.py

EMAIL_HOST = 'smtp.gmail.com'
EMAIL_USE_TLS = True
EMAIL_PORT = 587
EMAIL_HOST_USER = 'yourusername@gmail.com'
EMAIL_HOST_PASSWORD = 'yourpassword'
DEFAULT_FROM_EMAIL = EMAIL_HOST_USER

email인증 서비스를 제공하기 위해 입력해주자. gmail에서는 프로필로 가서 보안 탭의 앱별 암호를 설정해서 입력해줘야한다. 

 

 

3. dev.py

# EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'

allauth 이메일 인증을 사용하기 위해서 django email기능은 주석처리 하면 된다. 

 

 

4. forms.py

from django import forms
from django.utils.translation import gettext_lazy as _

class SignupForm(forms.Form):
    first_name = forms.CharField(max_length=30, label=_("First name"))
    last_name = forms.CharField(max_length=30, label=_("Last name"))
    display_name = forms.CharField(max_length=30, label=_("Display name"), help_text=_("Will be shown e.g. when commenting."))

    def signup(self, request, user):
        user.first_name = self.cleaned_data['first_name']
        user.last_name = self.cleaned_data['last_name']
        user.display_name = self.cleaned_data['display_name']
        user.save()

가입할 때, first, last, display이름을 입력받고 사용자 정보에 입력하기 위해 만들어준다. 

 

cleaned_data : 검증에 통과한 값을 사전타입으로 제공 (딕셔너리)

 

 

5. signup.html

{% extends 'account/base_card.html' %}

{% load i18n %}

{% block head_title %}{% trans "Sign Up" %}{% endblock %}

{% block card-header %}
<h3>{% trans "Sign Up" %}</h3>
{% endblock %}

{% block card-body %}

<form method="POST" action="{% url 'account_signup' %}" class="needs-validation" novalidate>
    {% csrf_token %}
    <div class="form-row">
        <div class="form-group col-md-6">
            {% with field=form.email %}{% include "account/form_field.html" %}{% endwith %}
        </div>
        <div class="form-group col-md-6">
            {% with field=form.display_name %}{% include "account/form_field.html" %}{% endwith %}
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-6">
            {% with field=form.password1 %}{% include "account/form_field.html" %}{% endwith %}
        </div>
        <div class="form-group col-md-6">
            {% with field=form.password2 %}{% include "account/form_field.html" %}{% endwith %}
        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-6">
            {% with field=form.first_name %}{% include "account/form_field.html" %}{% endwith %}
        </div>
        <div class="form-group col-md-6">
            {% with field=form.last_name %}{% include "account/form_field.html" %}{% endwith %}
        </div>
    </div>
    <button type="submit" class="btn btn-outline-primary">{% trans "Sign Up" %}</button>
</form>

{% endblock %}

{% block card-footer %}
<p>{% trans "Already have an account?" %} <a href="{% url 'account_login' %}">{% trans "Sign In" %}</a></p>
{% endblock %}

 

 

추가)

사이트 주소를 바꾸고 싶다면 django-admin에서 site에서 example.com을 바꿔주고 base.py 에서 다음과 같이 수정하면 된다. 

 

BASE_URL = 'http://PythonEatsTail.com'

 

https://www.pythoneatstail.com/en/overview-all-articles/github-secret-keys-and-other-local-settings/

 

Github, secret keys and other local settings - PythonEatsTail

Most of you will be familiar with Github and will know that you shouldn't put things like secret keys, email passwords, database passwords etc. in your repository. There are many ways to do that, some use separate programs for that, some manually adjust se

www.pythoneatstail.com

 

 

1. gitignore

db.sqlite3
env/
.env
local.py
*.mo
.coverage
media/**

 

 

2. local.py

데이터베이스 세팅과 django secret_key를 넣는다.

SECRET_KEY = 'zmmyskj$$b0d6y%1j6&fkq+#6b5m#_+-=c@r@lphil3o2bkcrj'

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql',
        'NAME': 'db_pet',
        'USER': 'usr_pet',
        'PASSWORD': '1234',
        'HOST': '127.0.0.1',
        'PORT': '5432',
    }
}

 

- SECRET_KEY의 사용 용도

  • django.contrib.sessions.backends.cache 이외의 session backend를 사용하고 있거나, 기본 get_session_auth_hash()를 사용하는 모든 sessions
  • CookieStorage 혹은 FallbackStorage를 사용하는 모든 messages 
  • 모든 PasswordResetView

다른 키가 제공되지 않는 암호화 서명 사용 시 사용된다. 

 

 

3. secret_key generator

from django.core.management.utils import get_random_secret_key
get_random_secret_key()

 

 

4. psql

ALTER USER usr_pet WITH PASSWORD '<new password>';

https://www.pythoneatstail.com/en/overview-all-articles/setting-login-allauth-django/

 

Setting up validated login with allauth in Django - PythonEatsTai

In this tutorial we are going to implement the login functionality of the allauth package, with nicely formatted and user friendly templates.

www.pythoneatstail.com

 

+ Recent posts