Как сохранить поле объекта из другой модели Django - PullRequest
0 голосов
/ 19 апреля 2020

Во-первых, я расширяю AbstractUser следующим образом:

class MyProfile(AbstractUser):
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    full_name = models.CharField(max_length=255)
    id_number = models.CharField(max_length=14)

    def __str__(self):
        return self.full_name

    def save(self, *args, **kwargs):
        self.full_name = '{0} {1}'.format(self.first_name, self.last_name)
        super().save(*args, **kwargs)

А затем ссылка на другую модель, подобную этой:

class MyModel(models.Model):
    member = models.OneToOneField(MyProfile, on_delete=models.CASCADE)
    description = models.CharField(max_length=255)

    def __str__(self):
        return self.member

И эта форма:

class MyModelForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    class Meta:
        model = MyModel
        fields = ('description')

    full_name = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))
    id_number = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))
    description = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))

И это вид:

def applicationdata(request):
   if request.method == 'POST':
      form = MyModelForm(request.POST or None) 
      if form.is_valid():
         form.save()
      return HttpResponseRedirect('/index/')
      else:
         print(form.errors)
   else:
      form = MyModelForm()

   context = {
      'form': form,
   }
   return render(request, 'index.html', context)

Мой вопрос:

  • Как отобразить поле full_name & id_number поле вместо member поле MyModelForm ?

  • И как сохранить эти поля с помощью applicationdata просмотров в поле member в MyModel модели?

UPDATE

  1. Я обновил модель AbstractUser, потому что я забыл добавить имя и фамилию и забыл упомянуть, если я использую allauth
  2. Я обновил форму с помощью init

Ответы [ 3 ]

0 голосов
/ 27 апреля 2020

сначала вы можете удалить поля first_name и last_name, поскольку вы можете получить его из full_name

class MyProfile(AbstractUser):
    full_name = models.CharField(max_length=255)
    id_number = models.CharField(max_length=14)

    def __str__(self) -> str:
        return self.full_name

    @property
    def first_name(self) -> str:
        return self.full_name.split(' ')[0]

    @property
    def last_name(self) -> str:
        if self.full_name.split(' ') > 1:
            return self.full_name.split(' ')[1]
        return ''

class MyModelForm(forms.ModelForm):

    full_name = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))
    id_number = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))

    class Meta:
        model = MyModel
        fields = ('description')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.fields['description'].widget = forms.TextInput(attrs={'class': "form-control"})

    def save(self, *args, **kwargs):
        kwargs['commit'] = False
        my_model = super().save(*args, **kwargs)
        MyProfile.objects.update_or_create(
            full_name=self.cleaned_data['full_name'],
            id_number=self.cleaned_data['id_number'],
            mymodel=my_model
        )


, если объект MyProfile уже существует, вы можете использовать его для заполните поля формы автоматически с помощью __init__

    def __init__(self, my_profile: MyProfile, *args, **kwargs):
        kwargs.update(initial={
            # 'field': 'value'
            'full_name': my_profile.full_name,
            'id_number': my_profile.id_number
        })
        super().__init__(*args, **kwargs)
        self.fields['description'].widget = forms.TextInput(attrs={'class': "form-control"})
0 голосов
/ 30 апреля 2020

Как отобразить поле full_name и поле id_number вместо поля члена в MyModelForm?

, если вы хотите показать его, чтобы изменить его впоследствии, вы должны переопределить метод __init__ для установить начальные данные в двух полях: может быть, этот ответ может помочь

И как сохранить эти поля с помощью представлений applicationdata в поле члена в модели MyModel?

entity = form.save() # this gives you the updated MyModel instance

затем сохраните данные из формы в связанной модели, например:

 entity.member.full_name = form.cleaned_data['full_name']

должно работать в соответствии с: этот ответ

0 голосов
/ 27 апреля 2020

Вместо использования ModelForm здесь лучше использовать Form, потому что мы определенно не используем поле моделей. Ваш файл forms.py должен выглядеть так:

class MyModelForm(forms.Form):

    full_name = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))
    id_number = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))
    description = forms.CharField(required=False, label="", widget=forms.TextInput(attrs={'class': "form-control"}))

, в то время как наш метод представлений должен быть полностью настроен в соответствии с полями, а данные должны быть сохранены. Измените метод views.py на этот

def applicationdata(request):
   if request.method == 'POST':
      form = MyModelForm(request.POST or None) 
      if form.is_valid():
          profile = MyProfile.object.create(full_name=request.POST['full_name'], id_number=request.POST['id_number'])
          if profile is not None:
              MyModel.object.create(description=request.POST['description'], member=profile.pk)
              return HttpResponseRedirect('/index/')
          else:
              form.add_error('profile_out_of_bound', "please try to fill correct details!")

      print(form.errors)
   else:
      form = MyModelForm()

   context = {
      'form': form,
   }
   return render(request, 'index.html', context)

Исправьте меня, если это не сработает.

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