I want to create user from extended Profile model , its done using api request , but from form it is not working . In api request body I am passing three fields only name,email,and phone_number, so that password is making through random automatically.
class ProfileManager(model.Manager):
def create(self, email,phone_number, **kwargs):
password=str(random.random())[2:8]
user = User(username=phone_number)
user.set_password(password)
user.save()
profile = Profile(
user=user,
email=email,
**kwargs
)
profile.save()
if am using form like
class CustomerCreateForm(forms.ModelForm):
name =forms.CharField(label='Name', max_length=32)
phone_number = forms.CharField(label='Name', max_length=32)
class Meta:
model=Profile
fields=['email','name','phone_number']
this ,it making error like user (1048, "Column 'user_id' cannot be null") because my profile model look like
class Profile(models.model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
name = models.CharField(max_length=50)
email = models.CharField(max_length=50,null=True, blank=True)
phone_number = models.CharField(max_length= 15, null=True, blank=True)
So from here i understood that ProfileManager is not dependent with form, so i need to make def validate(self,attrs) like function and differet manger for form , but i don't know how to do this due to newbie. Any help is appreciated
The solution would depend on how you are using your form... I see two solutions:
If you set the commit argument of the form save method to False, the model object will have its attribute updated according but not saved in the database. This allows you to further work on it before persisting the changes.
For example, in a CreateView, you would override the form_valid method if your are using Class Based View:
def form_valid(self, form):
obj = form.save(commit=False) # obj.save() not called by the form
obj.user = self.request.user # or other user source
obj.save() # model instance saved in db with validated constraints
return HttpResponseRedirect(self.get_success_url())
If using function views, the idea is the same:
def my_view(request):
# Omitting HTTP method check for simplicity
my_form = Form(data=request.Post)
if my_form.is_valid():
obj = form.save(commit=False)
obj.user = self.request.user
obj.save()
return HttpResponseRedirect(self.get_success_url())
# template stuff goes here
This is not as clean as the first one... You override the constructor and save method of your form to add the missing fields value:
class MyForm(forms.ModelForm): # Meta here
def __init__(self, user, **kwargs):
self.user = user
super().__init__(**kwargs)
def save(self, commit=True):
# add missing fields
self.instance.user = self.user
# and proceed with normal form flow
return super().save(commit)