Django ModelForm does not save data in database

Beginner Django has a lot of trouble getting forms. Yes, I worked on the textbook and browsed the Internet many times - I have a mixture of what I find here and on other sites. I am using Python 2.7 and Django 1.5. (although the official documentation is extensive, it usually assumes that you know most of it — not very well, like a beginner’s guide or even an extended tutorial).

I am trying to create a form for "advanced" user details - for example. company name, street address, etc., but the form data is not stored in the database.

At first I tried to create a model that extends the standard User model, but I abandoned this - I had to modify too much, and it was part of nitty gritty, which was far beyond me at this stage. So instead, I created a new model called UserProfile :

 class UserProfile(models.Model): user = models.ForeignKey(settings.AUTH_USER_MODEL, unique=True) company = models.CharField(max_length=50, blank=True) address1 = models.CharField(max_length=50, blank=True) address2 = models.CharField(max_length=50, blank=True) city = models.CharField(max_length=20, blank=True) region = models.CharField(max_length=20, blank=True) postcode = models.CharField(max_length=10, blank=True) country = models.CharField(max_length=20, blank=True) phone = models.CharField(max_length=30, blank = True) 

I have seen various online links about whether I should reference the user model using ForeignKey (as mentioned above) or using OneToOne.

I am trying to use ModelForm (keep it simple for what should be a simple form). Here are my forms.py

 from django.forms import ModelForm from .models import UserProfile class UserDetailsForm(ModelForm): class Meta: model = UserProfile fields = ['company','address1','address2','city','region', 'postcode','country','phone'] 

Here is my view:

 def UserDetailsView(request): #f = 0 if request.method == 'POST': f = UserDetailsForm(request.POST, instance = request.user) if f.is_valid(): f.save() else: f = UserDetailsForm(request.POST , instance = request.user) print "UserDetails objects: ", (UserProfile.objects.all()) return render_to_response('plagweb/console/profile.html', { 'form': f}, context_instance=RequestContext(request)) 

(yes, there is inconsistency in UserProfile and UserDetail - this is the product of my entire hack and will be fixed after I receive it)

Diagnostics shows f.is_valid() returning True. Similarly, the diagnostics show UserProfile.objects.all() as empty. I tried this in the above view after saving (), and also in the Django console.

Here is my template:

  <form method="POST" action=""> <table>{{ form }}</table> <input type="submit" value="Update" /> {% csrf_token %} </form> 

At the moment, the main problem is that the form data is not stored in the database. I don't know if it is readable or not (when I have data in the database ...)

One thought is that a User connection might cause a problem?


Additions, following from Daniel Roseman helpful comment / help:

Now the form is saved correctly (confirmed by diagnostics and command line checks. However, when I return to the form, it does not display the existing data. The form is displayed with empty data fields. As far as I can tell, I am passing the instance data correctly.

Is there a ModelForm parameter that needs to be changed?

The view has been changed here:

 def UserDetailsView(request): #print "request co:", request.user.profile.company f = UserDetailsForm(request.POST, instance = request.user.profile ) if request.method == 'POST': if f.is_valid(): profile = f.save(commit=False) profile.user = request.user profile.save() return render_to_response('plagweb/console/profile.html', { 'form': f}, context_instance=RequestContext(request)) 

Diagnostics show that request.user.profile set correctly (in particular, the company field). However, the form is displayed with empty fields. The HTML source also does not display data values. As an additional check, I also tried some diagnostic patterns:

 <table border='1'> {% for field in form%} <tr> <td>{{field.label}}</td> <td>{{field.value}}</td> </tr> {% endfor%} </table> 

This displays the field labels correctly, but all values ​​are specified as None .

For completeness, the UserProfile user field is now defined as user = models.OneToOneField(settings.AUTH_USER_MODEL) , and the lambda User.profile expression does not change.

+4
source share
4 answers

I'm not sure what the problem is, but one problem is that you pass instance=request.user when you instantiate the form. This is definitely not true: request.user is an instance of the user, whereas the form is based on UserProfile .

Instead, you want to do something like this:

 f = UserDetailsForm(request.POST) if f.is_valid(): profile = f.save(commit=False) profile.user = request.user profile.save() 

As for ForeignKey vs OneToOne, you should absolutely use OneToOne. Advice on using ForeignKeys was provided some time before the release of Django 1 - almost five years ago, because the initial implementation of OneToOne was poor and had to be rewritten. You, of course, will not find the actual documentation in which it is recommended to use FK here.

Edit after comments Now the problem is that you create a form with the first parameter, data, even if the request is not POST, and therefore request.POST is an empty dictionary. But the data parameter, even if it is empty, takes precedence over what is passed as source data.

You should go back to the original form instance template in the if , but you don't have to pass request.POST when you execute this sentence to else .

+16
source

This is a kind of old topic, but I hope this helps someone. I struggled with a similar problem, I initiated an object from the database, updated the field, called the save () function, and nothing happened.

 user = User.objects.get(username = example_string) user.userprofile.accepted_terms = True user.userprofile.save() 

The accept_terms field has been added recently and this has been a problem. First try python manage.py makemigrations and python manage.py migrate if this does not help you clean up the database.

The solution in my case was to clean up the database .

+1
source
 UserDetailsForm(request.POST, instance = db_obj_form) 

db_obj should be the object of the UserProfile table that you want to save.

0
source

Remember to register your model form in the admin.py file. This is a common mistake.

Register your models here.

 from . models import advancedUserForm admin.site.register(advancedUserForm) 
0
source

Source: https://habr.com/ru/post/1497525/


All Articles