Как передать данные для OneToOneField при тестировании? - PullRequest
0 голосов
/ 23 июня 2019

У меня есть signupView, которое показывает 2 формы: SignUpForm и ProfileForm.

В основном SignUpForm собирает данные типа first_name, last_name, user_name, email,password1, password2.

И ProfileForm собирает такие данные, как dni, birthdate, shipping_address и т. Д.

Я тестирую ProfileForm, но я не знаю, как передать информацию для пользовательского поля модели профиля, это OneToOneField для модели пользователя.

 user = models.OneToOneField(User, on_delete=models.CASCADE)

формы.py:

class ProfileForm(ModelForm):
    MONTHS = {
        1:'ene', 2:'feb', 3:'mar', 4:'abr',
        5:'may', 6:'jun', 7:'jul', 8:'ago',
        9:'set', 10:'oct', 11:'nov', 12:'dic'
    }

    def __init__(self, district_list, province_list, department_list, *args, **kwargs):
        super(ProfileForm, self).__init__(*args, **kwargs)
        self.fields['shipping_district'] = forms.ChoiceField(label='Distrito', choices=tuple([(name, name) for name in district_list]))
        self.fields['shipping_province'] = forms.ChoiceField(label='Provincia', choices=tuple([(name, name) for name in province_list]))
        self.fields['shipping_department'] = forms.ChoiceField(label='Departamento', choices=tuple([(name, name) for name in department_list]))


    dni = forms.CharField(label='DNI', max_length=100, required=True)
    phone_number = forms.CharField(label='Celular')
    birthdate = forms.DateField(label='Fecha de nacimiento', widget=SelectDateWidget(years=range(1980, 2012), months=MONTHS))
    shipping_address1 = forms.CharField(label='Dirección de envío', max_length=100, required=True)
    shipping_address2 = forms.CharField(label='Referencia (opcional)', max_length=100, required=False)

    class Meta:
        model = Profile
        fields = ('dni', 'phone_number', 'birthdate', 'shipping_address1',
                  'shipping_address2', 'shipping_department', 'shipping_province', 'shipping_district')

models.py:

class Profile(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    birthdate = models.DateField(null=True, blank=True)
    dni = models.CharField(max_length=30, blank=True)
    phone_number = models.CharField(max_length=30, blank=True)
    shipping_address1 = models.CharField(max_length=100, blank=False)
    reference = models.CharField(max_length=100, blank=False)
    shipping_department = models.CharField(max_length=100, blank=False)
    shipping_province = models.CharField(max_length=100, blank=False)
    shipping_district = models.CharField(max_length=100, blank=False)
    photo = models.ImageField(upload_to='profile_pics', default='profile_pics/default_profile_pic_white.png')

    def __str__(self):
        return str(self.user.first_name) + "'s profile"

test_forms.py:

from django.test import TestCase
from django.utils import timezone
from django.urls import reverse
from shop.forms import SignUpForm, ProfileForm
import datetime


#coverage run manage.py test shop/tests -v 2

class SignUpFormTest(TestCase):
    def test_signup_form(self):
        form_data = {'first_name': 'oma',
                     'last_name': 'gonza',
                     'username': 'omagonza',
                     'email': 'oma.gonzales@gmail.com',
                     'password1': 'caballo123',
                     'password2': 'caballo123'}
        form = SignUpForm(data=form_data)
        self.assertTrue(form.is_valid())

    def test_profile_form(self):
        district_list = 'Lima'
        province_list = 'Lima'
        department_list = 'Lima'
        form_data = {'user': #¿?¿?¿?
                     'dni': 454545,
                     'phone_number': 96959495,
                     'birthdate': datetime.datetime.now(),
                     'shipping_address1': 'Urb. Los Leones',
                     'shipping_address2': 'Colegio X',
                     'shipping_department': 'Lima',
                     'shipping_province': 'Lima',
                     'shipping_province': 'Ate'}
        form = ProfileForm(district_list=district_list, province_list=province_list,
                           department_list=department_list, data=form_data)
        self.assertTrue(form.is_valid())  


AttributeError: 'ProfileForm' object has no attribute 'birthdate'

У меня есть ProfileForm, который создан на основе SignUpForm.

views.py:

@transaction.atomic
def signupView(request):
    peru = Peru.objects.all()
    department_list = set()
    province_list = set()
    district_list = set()
    for p in peru:
        department_list.add(p.departamento)
    department_list = list(department_list)
    if len(department_list):
        province_list = set(Peru.objects.filter(departamento=department_list[0]).values_list("provincia", flat=True))
        province_list = list(province_list)
    else:
        province_list = set()
    if len(province_list):
        district_list = set(
            Peru.objects.filter(departamento=department_list[0], provincia=province_list[0]).values_list("distrito",
                                                                                                         flat=True))
    else:
        district_list = set()

    if request.method == 'POST':

        peru = Peru.objects.all()
        department_list = set()
        province_list = set()
        district_list = set()
        for p in peru:
            department_list.add(p.departamento)
        department_list = list(department_list)
        if len(department_list):
            province_list = set(
                Peru.objects.filter(departamento__in=department_list).values_list("provincia", flat=True))

            province_list = list(province_list)
        else:
            province_list = set()
        if len(province_list):
            district_list = set(
                Peru.objects.filter(departamento__in=department_list, provincia__in=province_list).values_list(
                    "distrito",
                    flat=True))
        else:
            district_list = set()

        #####

        user_form = SignUpForm(request.POST)
        profile_form = ProfileForm(district_list, province_list, department_list, request.POST, request.FILES)

        if user_form.is_valid() and profile_form.is_valid():
            user = user_form.save(commit=False)
            user.is_active = False
            user.save()
            username = user_form.cleaned_data.get('username')
            signup_user = User.objects.get(username=username)
            customer_group = Group.objects.get(name='Clientes')
            customer_group.user_set.add(signup_user)
            raw_password = user_form.cleaned_data.get('password1')
            user.refresh_from_db()  # This will load the Profile created by the Signal

            profile_form = ProfileForm(district_list, province_list, department_list, request.POST, request.FILES,
                                       instance=user.profile)  # Reload the profile form with the profile instance
            profile_form.full_clean()  # Manually clean the form this time. It is implicitly called by "is_valid()" method

            profile_form.save()  # Gracefully save the form


            current_site = get_current_site(request)
            mail_subject = 'Confirmación de correo electrónico'
            message = render_to_string('accounts/acc_activate_email.html', {
                'user': user,
                'domain': current_site.domain,
                'uid': urlsafe_base64_encode(force_bytes(user.pk)),
                'token': account_activation_token.make_token(user),
            })
            to_email = user_form.cleaned_data.get('email')
            # to_email = 'oma.gonzales@gmail.com'
            from_email = 'stickersgallito@stickersgallito.pe'
            email = EmailMessage(
                mail_subject, message, to=[to_email], from_email=from_email
            )
            email.send()

            return redirect('shop:email_confirmation_needed')


        else:
            pass


    else:

        user_form = SignUpForm()

        profile_form = ProfileForm(district_list, province_list, department_list)

    return render(request, 'accounts/signup.html', {
        'user_form': user_form,
        'profile_form': profile_form
    })

1 Ответ

4 голосов
/ 23 июня 2019

Поскольку для ProfileForm требуется объект user для тестирования, вы можете создать метод setUp в своем классе SignupFormTest, чтобы создать тестовый объект user и использовать его в своем методе test_profile_form(). Пожалуйста, найдите код ниже:

from django.contrib.auth import get_user_model

class SignUpFormTest(TestCase):

    def setUp(self):
            self.user = get_user_model().objects.create_user(
                username='testuser', email='testemail@example.com',
                password='secret')

    def test_profile_form(self):
        district_list = 'Lima'
        province_list = 'Lima'
        department_list = 'Lima'
        form_data = {'user': self.user
                     'dni': 454545,
                     'phone_number': 96959495,
                     'birthdate': datetime.datetime.now(),
                     'shipping_address1': 'Urb. Los Leones',
                     'shipping_address2': 'Colegio X',
                     'shipping_department': 'Lima',
                     'shipping_province': 'Lima',
                     'shipping_province': 'Ate'}
        form = ProfileForm(district_list=district_list, province_list=province_list,
                           department_list=department_list, data=form_data)
        self.assertTrue(form.is_valid())  

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...