如何在Django中使用单一表单创建用户和个人资料?

时间:2020-02-18 14:19:50

标签: python django django-3.0

我已经在PreferenceFragmentCompat中创建了一个public class SettingsFragment extends PreferenceFragmentCompat { Activity activity = null; String TAG = "SettingsFragment"; @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { setPreferencesFromResource(R.xml.root_preferences, rootKey); } @Override public void onAttach(@NonNull Context context) { super.onAttach(context); activity = getActivity(); } // Add this with modified logic @Override protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) { PreferenceCategory category = findPreference("MyPreference"); category.setLayoutResource(R.layout.preference_group_layout); MyAdapter myAdapter = new MyAdapter(category); final int tot = 10; final int middle = tot / 2; for (int i = 1; i <= tot; i++) { Preference preference = new Preference(activity); preference.setKey("P" + i); int layout = R.layout.preference_layout; switch (i) { case 1: layout = R.layout.preference_layout_first; break; case middle: layout = R.layout.preference_layout_middle; break; case tot: // last layout = R.layout.preference_layout_last; break; } preference.setLayoutResource(layout); category.addPreference(preference); Log.d(TAG, "" + category.getPreferenceCount()); myAdapter.notifyDataSetChanged(); } return myAdapter; } } 模型,该模型旨在用作客户(用户)个人资料。

Clients

此模型通过名为models.py的OneToOneField连接到Django用户。

我创建了一个表单,该表单能够将数据添加到class Clients(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) first_name = models.CharField(max_length=30, verbose_name="Primeiro Nome") last_name = models.CharField(max_length=30, verbose_name="Apelido") address = models.CharField(max_length=200, verbose_name="Morada") nif = models.CharField(max_length=9, verbose_name="NIF", validators=[RegexValidator(r'^\d{1,10}$')], primary_key=True) mobile = models.CharField(max_length=9, verbose_name="Telemóvel", validators=[RegexValidator(r'^\d{1,10}$')]) email = models.CharField(max_length=200, null=True, verbose_name="Email") avatar = models.ImageField(null=True) def __str__(self): return "%s %s" % (self.first_name, self.last_name) class Meta: verbose_name_plural = "Clientes" @receiver(post_save, sender=User) def update_user_profile(sender, instance, created, **kwargs): if created: Clients.objects.create(user=instance) instance.profile.save() 中的user模型中:

Clients

我如何通过这种单一形式添加一个forms.pyfrom django import forms from django.contrib.auth.forms import UserCreationForm from django.contrib.auth.models import User from django.core.validators import RegexValidator class SignUpForm(UserCreationForm): first_name = forms.CharField(max_length=30, label="Primeiro Nome") last_name = forms.CharField(max_length=30, label="Apelido") address = forms.CharField(max_length=200, label="Morada") nif = forms.CharField(max_length=9, label="NIF", validators=[RegexValidator(r'^\d{1,10}$')]) mobile = forms.CharField(max_length=9, label="Telemóvel", validators=[RegexValidator(r'^\d{1,10}$')]) email = forms.CharField(max_length=200, label="Email") class Meta: model = User fields = ('username', 'password1', 'password2', 'first_name', 'last_name', 'address', 'nif', 'mobile', 'email') 字段,以便通过OneToOneField创建与该配置文件相关的用户?

编辑

上述文件的新版本。现在,它创建了用户,但是username的所有其他字段都为空。

我的password

Clients

1 个答案:

答案 0 :(得分:1)

您添加的字段只是常规表单字段,而django对如何保存这些值一无所知。因此,您需要覆盖表单的save()方法或将其保存在视图中。这是您开始在视图中保存它们的方法,

if form.is_valid():
    user = form.save()  # this creates the user with first_name, email and last_name as well!
    user.refresh_from_db()  # load the profile instance created by the signal
    user.clients.address = form.cleaned_data.get('address')
    user.clients.nif = form.cleaned_data.get('nif')
    user.clients.mobile = form.cleaned_data.get('mobile')
    user.clients.save()
    login(request, user)
    return redirect('clientes')

注意:我对视图中的first_namelast_nameemail不做任何事情,它们是User模型的字段,因此它们已经被保存了form.save()会自动执行。您应该从Clients模型中删除它们。

注2:将Clients模型重命名为Client将使您的代码更具可读性。您应该始终对模型使用单数。这样一来,您可以进行user.client.address,它比user.clients.address更有意义,因为它是一对一的字段。

或者,您可以覆盖表单的save()方法,该方法是我更喜欢的一种方法,因为我认为视图不关心如何保存用户的个人资料:

# in SignupForm(UserCreationForm):
def save(self, commit=True):
    user = super().save(commit)  # this creates the new user
    if commit:
        user.refresh_from_db()  # not sure if this is needed
        user.clients.nib = self.cleaned_data.get('nib')
        user.clients.address = self.cleaned_data.get('address')
        user.clients.mobile = self.cleaned_data.get('mobile')
        user.clients.save()
    return user