[英]django inlineformset won't save
我想我错过了一些愚蠢的东西,但是我无法使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))
表格
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)。 尽管如此,inlineform不会保存。 我试图做一个自定义的def save(),但是没有成功。
视图中的变量“ form”连接到Profiles,而“ profile_formset”连接到ProfileData。
我通常在这里问问题时不屑一顾,如果您发现我不清楚,我将进行编辑。
尽管这不是解决方案,但这里有几件事要注意:
1)我不明白为什么选择字段后仍使用排除。
2)您正在form.py和views.py中进行两次密码匹配
3)据我所知,在forms.py中,用于验证字段的方法应类似于clean_fieldname。
如果我错了,请纠正我。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.