• 카테고리

    질문 & 답변
  • 세부 분야

    풀스택

  • 해결 여부

    미해결

저희가 html에서 form.as_p 로 호출할때

20.08.31 21:49 작성 조회수 293

1

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(instancefilename): # 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(150150)],
                                 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

답변을 작성해보세요.

0

sincc0715님 ~ 요기서부터는 컨테이너를 공유해주시는게 더 해결이 빠르실것 같으세요~ ㅎ아마 큰 문제 아니실거에요 저희 귀찮치 않아요 다만 ㅠ ㅠ 먹고사는게 바쁘다 보니 답변이 늦어질때가 있습니다 ㅎ 이해 부탁드릴게요 ~ ^ ^