Django Идентификация представления на основе классов и формирование нескольких моделей - PullRequest
2 голосов
/ 09 марта 2019

У меня второй проект Django. В моем первом проекте я использовал все общие представления, только самые базовые формы были связаны непосредственно с пользовательской моделью, используя UpdateView.

В этом проекте я пытаюсь реализовать функциональность профиля пользователя. Моя пользовательская модель имеет несколько дополнительных фиктивных полей, чтобы я мог манипулировать данными. Это я называю моделью CustomUser. У меня также есть модель UserAddress, содержащая адреса, поскольку у пользователя может быть несколько адресов. Я пытался найти другие вопросы и получаю похожие вопросы, но всегда чего-то не хватает:

Представления на основе классов Django - UpdateView с двумя модельными формами - одна отправка

Использование нескольких моделей моделей с представлениями на основе классов

Несколько моделей в одной django ModelForm?

Django: несколько моделей в одном шаблоне с использованием форм

Я провел последний день или два в поисках «способа Джанго», чтобы делать то, что я хочу, и мне не повезло. Сначала я думал, что смогу использовать один шаблон, снабженный двумя ModelForms, обернутыми в один тег <form>. Затем представление будет обрабатывать каждую форму и обновлять модель CustomUser, а также создавать или обновлять модели UserAddress. Я выяснил, как объединить функциональность, используя базовый View CBV, но я подозреваю, что дублирую многие функции, которые я, вероятно, мог бы найти уже в Django. Это мой взгляд, когда я обрабатываю форму, создавая экземпляр вручную, и передаю context.

class UserDetailsView(View):

    def get(self, request):
        user = request.user
        user_basic = CustomUser.objects.get(pk=user.pk)
        basic_form = UserBasicForm(instance=user_basic)

        user_address = UserAddress.objects.get(user=user.pk)   
        billing_address_form = UserAddressForm(instance = user_address)

        context = {'basic_form':basic_form,'billing_address_form':billing_address_form}

        return render(request, 'mainapp/profile.html', context)

Моя post на данный момент такая же, как я еще не провела фактическую проверку и сохранение.

class UserBasicForm(forms.ModelForm):

    class Meta(forms.ModelForm):
        model = CustomUser
        fields = (
            'username',
            'first_name',
            'last_name',
            )
        labels = {
            'username':'Username',
            'first_name':'First Name',
            'last_name':'Last Name',
            }

class UserAddressForm(forms.ModelForm):

    class Meta(forms.ModelForm):
        model = UserAddress
        fields = (
            'description',
            'addressee',
            'company',
            'address_1',
            'address_2',
            'city',
            'prov_state',
            'post_zip',
            'country',
            )
        labels = {
            'description':'Address Description',
            'addressee':'Addressee',
            'company':'Company Name',
            'address_1':'Address',
            'address_2':'Address 2',
            'city':'City',
            'prov_state':'Province or State',
            'post_zip':'Postal or Zip Code',
            'country':'Country',
            }

class CustomUser(AbstractUser):
    objects = CustomUserManager()

    def __str__(self):
        return self.email

class UserAddress(models.Model):
    user = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE,)

    description = models.CharField(max_length = 256, default='Description')

    addressee = models.CharField(max_length = 256,)
    company = models.CharField(max_length = 256, default='Self')
    address_1 = models.CharField(max_length = 256,)
    address_2 = models.CharField(max_length = 256,)
    city = models.CharField(max_length = 256,)
    prov_state = models.CharField(max_length = 256,)
    post_zip = models.CharField(max_length = 256,)
    country = models.CharField(max_length = 256,)

    def __str__(self):
        return self.description

Пожалуйста, будьте осторожны со мной, я приму большинство предложенных советов.

Редактировать После рассмотрения некоторых других вопросов SO и примеров форм Django выясняется, что окончательный ответ, вероятно, не настолько материален. Тем не менее, мое наблюдение заключается в том, что для встроенных CBV Django «лучшим» базовым представлением является то, что вы можете минимизировать или упростить добавляемый код. Использование TemplateView или FormView для моего проекта в этом случае зависит только от того, какие методы я выберу переписать или переопределить, и для этого я все еще открыт для предложений.

1 Ответ

1 голос
/ 09 марта 2019

Я бы сделал что-то вроде этого ( с улучшенными формами ):

class UserCreationMultiForm(MultiModelForm):
    form_classes = {
        'basic': UserBasicForm,
        'address': UserAddressForm,
    }


class UserDetailsView(View):
    template = "mainapp/profile.html"
    form_class = UserCreationMultiForm
    success_url = reverse_lazy('home')

    def form_valid(self, form):
        # Save the user first, because the profile needs a user before it
        # can be saved.
        user = form['basic'].save()
        address = form['address'].save(commit=False)
        address.user = user
        address.save()
        return redirect(self.get_success_url())

Затем переименуйте ваши формы в шаблоне на form.basic и form.address

...