我认为我错过了一些愚蠢的东西,但我不能让inlineformset与我合作。我的网站上有一个非常相似的代码,工作正常。原始代码用于注册,我试图对其进行修改,以便更新/更改用户数据。
models.py
class Profiles(AbstractBaseUser):
activation_key = Utils().activationKey()
email = models.EmailField(verbose_name = 'email address', max_length = 255, unique = True)
activation_code = models.CharField(max_length=40, default=activation_key)
is_active = models.BooleanField(default=True)
is_admin = models.BooleanField(default=False)
objects = ProfilesManager()
USERNAME_FIELD = 'email'
def get_email(self):
return self.email
def get_full_name(self):
# The user is identified by their email address
userdata = ProfileData.objects.get(uid_id=self.id)
return userdata.full_name
def get_short_name(self):
# The user is identified by their email address
return self.email
def __str__(self): # __unicode__ on Python 2
return self.email
def has_perm(self, perm, obj=None):
"Does the user have a specific permission?"
# Simplest possible answer: Yes, always
return True
def has_module_perms(self, app_label):
"Does the user have permissions to view the app `app_label`?"
# Simplest possible answer: Yes, always
return True
def __unicode__(self):
return u'%d' % self.id
@property
def is_staff(self):
"Is the user a member of staff?"
# Simplest possible answer: All admins are staff
return self.is_admin
class ProfileData(models.Model):
profile = models.ForeignKey(Profiles)
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
full_name = models.CharField(max_length=100)
image = models.ImageField(upload_to='media/user/avatar', blank=True, null=True)
def get_first_name(self):
return self.first_name
def get_last_name(self):
return self.last_name
def get_full_name(self):
return self.full_name
def get_avatar(self):
return self.image
def save(self, *args, **kwargs):
self.full_name = '{0} {1}'.format(self.first_name, self.last_name)
super(ProfileData, self).save(*args, **kwargs)
views.py
class ProfileView(TemplateView):
template_name = 'profiles/profile.html'
form = ProfileDataForm
formset = ProfileFormset
def get(self, request, user_id):
profile = ProfileData.objects.select_related('Profiles').filter(profile=user_id).first()
if request.user.id and user_id:
if int(request.user.id) is int(user_id):
instance = ProfileData.objects.filter(profile=request.user).first()
return render(request, self.template_name, {'form': self.form(instance=request.user), 'formset': self.formset(), 'profile': profile})
else:
return render(request, self.template_name, {'profile': profile})
@method_decorator(sensitive_post_parameters())
@method_decorator(csrf_protect)
@method_decorator(never_cache)
@method_decorator(api_view(['POST']))
@transaction.non_atomic_requests
def post(self, request, user_id):
form = self.form(request.POST, instance=request.user)
if form.is_valid():
if form.data['password'] == form.data['conf_password']:
transaction.set_autocommit(False)
try:
profile = form.save(commit=False)
profile_formset = self.formset(request.POST, request.FILES, instance=profile)
if profile_formset.is_valid():
print 'formset is valid...'
profile.save()
profile_formset.save()
finally:
transaction.set_autocommit(True)
else:
print 'Passwords doesn\'t match'
else:
print 'Form is not valid...'
user = ProfileData.objects.select_related().filter(profile=user_id).first()
return HttpResponseRedirect('/user/{0}/'.format(user_id))
forms.py
class ProfileDataForm(forms.ModelForm):
email = forms.CharField(max_length=100, label='', widget=forms.TextInput(attrs={'placeholder': 'E-mail', 'class': 'form-control'}), required=False)
password = forms.CharField(max_length=100, label='', widget=forms.PasswordInput(attrs={'placeholder': 'Password', 'class': 'form-control'}), required=False)
conf_password = forms.CharField(max_length=100, label='', widget=forms.PasswordInput(attrs={'placeholder': 'Confirm Password', 'class': 'form-control'}), required=False)
class Meta:
model = Profiles
fields = ['email', 'password', 'conf_password']
exclude = ('full_name', 'image', )
def clean_password2(self):
# Check that the two password entries match
password = self.cleaned_data.get('password')
conf_password = self.cleaned_data.get('conf_password')
if password and conf_password and password != conf_password:
raise forms.ValidationError('Passwords don\'t match')
return conf_password
def save(self, commit=True):
print 'saving form...'
# Save the provided password in hashed format
user = super(ProfileDataForm, self).save(commit=False)
user.set_password(self.cleaned_data['password'])
if commit:
user.save()
return user
ProfileFormset = inlineformset_factory(Profiles, ProfileData,
exclude=('full_name', ),
can_delete=False,
extra=1,
widgets={
'first_name': forms.TextInput(attrs={'placeholder': 'First name', 'class': 'form-control'}),
'last_name': forms.TextInput(attrs={'placeholder': 'Last name', 'class': 'form-control'}),
},
labels={
'first_name': None,
'last_name': None
},
)
我已确保包含所有内容,没有错误,调试不会弹出并保存表单(views-> ProfilesViews-> post)。 尽管如此,内联形式并没有保存。我试图进行自定义def save(),但没有成功。
视图中的变量“form”连接到Profiles,而“profile_formset”连接到ProfileData。
我在这里提问时常常是垃圾,如果你发现我不清楚,我会编辑。
答案 0 :(得分:0)
虽然这不是一个解决方案,但这里有几点需要注意:
1)我不明白你选择字段后使用排除的原因
2)您在forms.py和views.py中进行了两次密码匹配
3)在forms.py中验证字段的方法,据我所知应该像clean_fieldname
如果我错了,请纠正我。