signup을 예로 들면
- 사용자명 , 이메일 주소 , 비번, 비번확인 , 닉네임 이런 순으로 되어있는데 어떻게 이런 순을 만들수 있고
- 또 form.py에서 username(사용자명) [a-zA-Z0-9]+ 이거 했었잖아요 이거가 이상한지 signup 이되질 않네요
저기 사용자명에 커서를 올리면 form title에 입력했던 오류가 납니다. 근데 왜 오류인지를 모르겠습니다.
https://github.com/shinwoo0715/instaclone/
여기 경로에서 two commit 들어가면 폴더 있는데 그게 최근건데 이거 보시기 그러시면 code 올려드릴께요
[forms.py]
from django import forms
from django.contrib.auth import get_user_model
from .models import Profile
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth.models import User
class LoginForm(forms.ModelForm):
class Meta:
model = User
fields = ['username' , 'password']
class SignupForm(UserCreationForm):
print("SignupForm 작동")
username = forms.CharField(label="사용자명" , widget=forms.TextInput(attrs={
"pattern" : "[a-zA-Z0-9]+",
"title" : "특수문자 , 공백 입력불가 다시 확인해주세요.",
}))
nickname = forms.CharField(label='닉네임')
picture = forms.ImageField(label='프로필사진' , required=False) # required꼭 필요한것이 아니다. ( 프로필 사진)
class Meta(UserCreationForm.Meta): # Meta라는 부분은 그대로 보내준다고 보면된다.
fields = UserCreationForm.Meta.fields + ("email" , )
def clean_nickname(self) : # 이것은 !! 유효성 검사이다. 내가 적은 nickname인 존재하는지 확인하는 함수
nickname = self.cleaned_data.get('nickname') # 입력한 nickname을 nickname변수에 넣어 검사
if Profile.objects.filter(nickname=nickname).exists():
raise forms.ValidationError("이미 존재하는 닉네임 입니다.")
return nickname
def clean_email(self):
email = self.cleaned_data.get("email")
User = get_user_model() # user모델을 통채로 가져와서 user에 넣습니다.
if User.objects.filter(email=email).exists(): # exists로 확인해서 이미존재한다면 실행해라
raise forms.ValidationError('사용중인 이메일 입니다.')
return email
def clean_picture(self):
picture = self.cleaned_data.get("picture")
if not picture: # picture에 아무것도 없다면 None을 주어라
picture = None
return picture
def save(self):
user = super().save()
Profile.objects.create(
user=user,
nickname = self.cleaned_data['nickname'],
picture = self.cleaned_data['picture']
)
return user
[models.py]
from django.conf import settings # settings를 가져온다.
from django.db import models
from imagekit.models import ProcessedImageField
from imagekit.processors import ResizeToFill
def user_path(instance, filename): # instance : 포토 모델 , filename : 사용자가 올린 file이름받아오자
from random import choice
import string
arr = [choice(string.ascii_letters) for _ in range(8)] # 이게 뭔지 알려면 media의 사진을 보면
#알수 있듯이 8자리의 난수 즉 아무 숫자 8자를 만들고 그사진의 이름으로 저장~!
pid = ''.join(arr)
extension = filename.split('.')[-1] # 파일이름의 확장자를 가져올꺼임 ㅅㄱ
return 'accounts/{}/{}.{}'.format(instance.user.username , pid , extension) # user.username에 맞는 폴더를 하나 만들어 주고
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL , on_delete=models.CASCADE) # 사용자 정보를 관리할수 있는 user model을 제공한다.
# on_delete에서 models.CASCADE가 사용된건 USER가 같을 수는 없기 때문에 USER 하나라는 것을 지정하는것이다.
nickname = models.CharField('별명' , max_length=20 , unique=True) # unique 다른 사람 들과 겹치지 않고 유니크를 True로 지정하자
# 사진
picture = ProcessedImageField(upload_to=user_path, # upload_to : 어디다가 저장할래
processors=[ResizeToFill(150, 150)],
format='JPEG',
options={'quality' : 90},
blank=True,) # 저장할때 사진의 크기
about = models.CharField(max_length=300 , blank=True) # blank = True라는 것은 비워도 된다는 것을 말한다.
GENDER_C = ( # 성별을 입력할수 있는 SELECTOR 박스를 만들자
('선택안함' , '선택안함'),
('여성' , '여성'),
('남성' , '남성'),
)
gender = models.CharField('성별(선택사항)' ,
max_length=10 , choices=GENDER_C,
default='N')
def __str__(self): # 외래키 설정 (외래키가 뭔말인지는 잘모르겠지만 일단 오케이)
return self.nickname
[views.py]
from django.shortcuts import render , redirect
from django.contrib.auth import authenticate , login # authenticate : 로그인 인증관련 기능,
from django.contrib.auth import logout as django_logout
from .forms import SignupForm , LoginForm
def signup(request):
if request.method == 'POST' :
username = request.POST.get("username")
email = request.POST.get("email")
password = request.POST.get("password1")
password2 = request.POST.get("password2")
print("username : \"", username,"\"")
print("emai : \"" , email,"\"")
print("password : ", password)
print("password again : ", password2)
form = SignupForm(request.POST , request.FILES) # 뒤에 request.FILE을 받은 이유는 우리가 회원가입을 할때
print("post전달 완료")
# 프로필도 받을 것이기 때문에 받은 것이다.
if form.is_valid():
print("데이터는 유효합니다.")
user = form.save()
return redirect('accounts:login')
else : # request.POST로 들어오지 않았다는 것은 오류사항이다.
print("데이터는 유효하지 않습니다.")
form = SignupForm()
print("post전달 완료 return 부분임")
return render(request, 'accounts/signup.html' , {
'form' : form ,
})
def login_check(request ):
if request.method == 'POST':
form = LoginForm(request.POST)
name = request.POST.get('username') # username으로 보내진 값을 변수에 저장
pwd = request.POST.get("password")
user = authenticate(username=name , password=pwd)
if user is not None:
login(request , user)
return redirect("/")
else:
return render(request , 'accounts/login_fail.html')
else:
form = LoginForm()
return render(request , 'accounts/login.html' , {'form' : form})
def logout(request): # logout은 매우 간단하다 우리가 아까 import한 auth 이다.
django_logout(request)
return redirect('/')
[signup.html]
{% extends 'accounts/layout.html' %}
{% block content %}
<div id="main_container">
<div class="form_container">
<div class="form">
<form action="" method='post' enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" class='submit_btn' value='가입'>
</form>
</div>
<div class="bottom_box">
<div>
<span>아이디가 있다면</span><a href="{% url 'accounts:login' %}">로그인</a>
</div>
</div>
</div>
</div>
{% endblock content %}
[admin.py]
from django.contrib import admin
from .models import Profile
# Register your models here.
@admin.register(Profile)
class ProfileAdmin(admin.ModelAdmin):
list_display = ['id' , 'nickname' , 'user']
list_display_links = ['nickname' , 'user']
search_fields = ['nickname']
진짜진자 귀찮겠지만 꼭봐주세요 저 힘으로는 불가능합니다... 회원가입이 되질 않아요..
계속 사용자명에서 그
username = forms.CharField(label="사용자명" , widget=forms.TextInput(attrs={
"pattern" : "[a-zA-Z0-9]+",
"title" : "특수문자 , 공백 입력불가 다시 확인해주세요.",
}))
저기 title부분이 자꾸 떠요 근데 이상한건 views에서 정확하게 forms로 전달이 되긴했는데 이유를 모르겠어요 error도 안뜨고 차라리 error가 뜨면 편한데 말이죠..
부탁드립니다...!!
답변 1