Display Two Forms in one Template in Django - python

My aim is to use Two models in One template. I have tried various ways around this and have had no success. Originally I had 2 views, 2 models and Two forms. After searching I found people using inlineformsets. So I dropped One of the Views and set-up the inlineformset.
This is currently where I am up to and seem to be hitting a wall.
The template renders to the browser and the 'object_list' part displays the database content as desired and the 'form' part renders the form and validates/saves the data correctly. The issue is with the 'formset'. No fields are rendered (I would expect to see a dropdown as the field is a foreignkey) and when the 'submit' button is pressed I get:
AttributeError at /settings/
'NoneType' object has no attribute 'save'
Any help in finding the error or pointers on alternative solutions would be greatly appreciated.
The Code:
models.py
from django.db import models
class RevisionSettings(models.Model):
global_revision_type = models.CharField(max_length = 5, unique=True, blank = True)
global_revision_description = models.CharField(max_length = 300, unique=True, blank = True)
class Meta:
ordering = ["global_revision_type"]
def __unicode__(self):
return u'%s %s' % (self.global_revision_type, self.global_revision_description)
class RevisionDefaultType(models.Model):
defaultrevisiontype = models.ForeignKey(RevisionSettings)
class Meta:
ordering = ["defaultrevisiontype"]
def __unicode__(self):
return unicode(self.defaultrevisiontype)
views.py
class RevisionSettingsView(CreateView):
template_name = 'settings/revisionsettings_view.html'
model = RevisionSettings
form_class = SettingsForm
success_url = reverse_lazy('globalsettings')
success_message = 'Successfully added your new revision type'
def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SettingsFormSet(instance = RevisionSettings)
return self.render_to_response(
self.get_context_data(form=form,
formset=formset))
def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
form = self.get_form(form_class)
formset = SettingsFormSet(self.request.POST)
if 'rev_settings_form_1' in self.request.POST:
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
elif 'rev_settings_form_2' in self.request.POST:
if formset.is_valid():
return self.formset_valid(formset)
else:
return self.form_invalid(formset)
def form_valid(self, form):
self.object = form.save()
self.object.save()
return HttpResponseRedirect(self.get_success_url())
def formset_valid(self, formset):
self.object.save()
formset.instance = self.object
formset.save()
return HttpResponseRedirect(self.get_success_url())
def form_invalid(self, form, formset):
return self.render_to_response(self.get_context_data(form=form,formset=formset))
def get_context_data(self, **kwargs):
kwargs['object_list'] = RevisionSettings.objects.order_by('global_revision_type')
return super(RevisionSettingsView, self).get_context_data(**kwargs)
forms.py
from django import forms
from django.forms.models import inlineformset_factory
from .models import RevisionSettings, RevisionDefaultType
class SettingsForm(forms.ModelForm):
class Meta:
model = RevisionSettings
class DefaultSettingsForm(forms.ModelForm):
class Meta:
model = RevisionDefaultType
SettingsFormSet = inlineformset_factory(RevisionSettings, RevisionDefaultType)
revisionsettings_view.html
(I have removed most of the HTML styling to keep the information to the point)
{% extends 'base_private.html' %}
{% block content %}
{% for object in object_list %}
<tr>
<td align="center">{{ object.global_revision_type }}</td>
<td align="center">{{ object.global_revision_description }}</td>
<td align="center"><span class="glyphicon glyphicon-remove-circle"></span></td>
</tr>
{% endfor %}
<form action = '{{ action }}' method = 'POST' class="form-horizontal" role="form">
{% csrf_token %}
<tr>
<td align="center">
{{ formset.management_form }}
{% for form in formset %}
{{ form.id }}
{{ form.defaultrevisiontype.label_tag }}
{{ form.defaultrevisiontype }}
{% endfor %}
</td>
</tr>
<span class="input-group-addon">
<input type = 'submit' name = 'rev_settings_form_2' value = 'Update Default Revision Type' class = 'btn btn-success'>
</span>
<td align="center">{{ form.global_revision_type }}{{ form.global_revision_type.errors }}</td>
<td align="center">{{ form.global_revision_description }}{{ form.global_revision_description.errors }}</td>
</tr>
<span class="input-group-addon">
<input type = 'submit' name = 'rev_settings_form_1' value = 'Add Revision Type' class = 'btn btn-success'>
</span>
</form>
{% endblock %}

Formsets are overkill for two forms. This is actually not too hard but poorly documented. You can make both forms the same form type, just give a prefix.
def parent_apply(request):
if request.method == 'POST':
parent_form = SignupForm(request.POST, prefix="parent")
student_form = StudentApplyForm(request.POST, prefix="student")
if parent_form.is_valid() and student_form.is_valid():
parent = parent_form.save()
student = student_form.save(parent)
else: messages.error(request, "Please correct the errors marked in red.")
else:
parent_form = SignupForm(prefix="parent")
student_form = StudentApplyForm(prefix="student")
return render_to_response('template_path/forms.html', { 'parent_form':parent_form, 'student_form':student_form }, context_instance=RequestContext(request))
The forms are just regular Django forms, no special settings required. You can change the order on which they validate and save one even if the other did not validate if you choose.
In your HTML Template, wrap both forms in the same tag and they will submit at the same time. If you want your forms to go to different view functions, specify two different elements.

Thanks for all the help. The pointers really helped me come to this solution. The main change was to 'def get' as shown below. I dropped the formset and passed the forms this way.
def get(self, request, *args, **kwargs):
form = self.settings_form_class
formset = self.default_form_class
return self.render_to_response(self.get_context_data(form = form, formset = formset))
I was unaware this was possible! Thanks again.

Related

Django inline formsets with Class-based view

I'm trying to do Django class-based CreateView inline formsets.
I have a product model and a productImage model and productImage is inline
everything looks fine but after i submit my product the images that are selected in formset will not save.
Here is my code
models.py:
class Product(models.Model):
name=models.CharField(max_length=200, db_index=True),
slug=models.SlugField(max_length=200, db_index=True, allow_unicode=True),
description=models.TextField(blank=True),
vector_column=SearchVectorField(null=True, editable=False),
meta={"indexes": (GinIndex(fields=["vector_column"]),)}
category = models.ForeignKey(Category, related_name='products',
on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
def get_absolute_url(self):
return reverse('shop:product_detail', args=[self.id, self.slug])
class ProductImage(models.Model):
product = models.ForeignKey(Product, default=None, on_delete=models.CASCADE)
image = models.ImageField(upload_to='products/%y/%m/%d')
def __str__(self):
return self.product.name
views.py
class ProductCreate(StaffAccessMixin, ProductFormValidMixin, ProductFieldsMixin,
CreateView):
model = Product
def get_context_data(self, **kwargs):
context = super(ProductCreate, self).get_context_data(**kwargs)
if self.request.POST:
context['product_image_formset'] = ProductImageFormset(self.request.POST)
else:
context['product_image_formset'] = ProductImageFormset()
return context
template_name = 'products/product-create-update.html'
ProductFormValidMixin:
class ProductFormValidMixin():
def form_valid(self, form):
context = self.get_context_data()
product_image_formset = context['product_image_formset']
if self.request.user.is_superuser:
self.obj = form.save()
if product_image_formset.is_valid():
product_image_formset.instance = self.obj
product_image_formset.save()
return redirect('administration:product-update', pk=self.obj.pk)
else:
self.obj = form.save(commit=False)
self.obj.available = False
return super().form_valid(form)
ProductFieldsMixin:
class ProductFieldsMixin():
def dispatch(self, request, *args, **kwargs):
if request.user.is_superuser:
self.fields = ["name",
"slug",
"description",
"category",
"price",
"available",
"image",
]
else:
raise Http404
return super().dispatch(request, *args, **kwargs)
forms.py:
from django.forms.models import inlineformset_factory
from .models import Product, ProductImage
ProductImageFormset = inlineformset_factory(Product, ProductImage, fields=('image',),
extra=3)
Formset template:
<h5 class="text-info">Add Product Metas</h5>
{{ product_image_formset.management_form|crispy }}
{% for form in product_image_formset.forms %}
<tr class="{% cycle 'row1' 'row2' %} formset_row-{{product_image_formset.prefix }}">
{% for field in form.visible_fields %}
<td>
{# Include the hidden fields in the form #}
{% if forloop.first %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% endif %}
{{ field.errors.as_ul }}
{{ field|as_crispy_field }}
</td>
{% endfor %}
</tr>
{% endfor %}
Everything is ok and my product form is saved after submit but the images i select in my form set won't save
Problem solved!
This code will work for other types of data but not for images and files
to solve this problem get_context_data function should be like this:
def get_context_data(self, **kwargs):
context = super(ProductCreate, self).get_context_data(**kwargs)
if self.request.POST:
context['product_image_formset']=ProductImageFormset(self.request.POST,
**self.request.FILES**)
else:
context['product_image_formset'] = ProductImageFormset()
return context
In my first code self.request.FILES was missing :) and because of that images couldn't saved

How to modify a form when returning it?

I am looking to modify a form from the user and return that different form in django, however I have tried many different ways, all in views.py, including:
Directly modifying it by doing str(form) += "modification"
returning a new form by newform = str(form) + "modification"
creating a different Post in models, but then I realized that wouldn't work because I only want one post
All the above have generated errors such as SyntaxError: can't assign to function call, TypeError: join() argument must be str or bytes, not 'HttpResponseRedirect', AttributeError: 'str' object has no attribute 'save', and another authority error that said I can't modify a form or something like that.
Here is a snippet from views.py:
class PostCreateView(LoginRequiredMixin, CreateView):
model = Post
fields = ['content']
title = ['title'] #
template_name = 'blog/post_new.html'
success_url = '/'
def form_valid(self, form):
#debugging
tempvar = (str(form).split('required id="id_content">'))[1].split('</textarea></td>')[0] #url
r = requests.get(tempvar)
tree = fromstring(r.content)
title = tree.findtext('.//title')
print(title)
form.instance.author = self.request.user
if "http://" in str(form).lower() or "https://" in str(form).lower():
if tempvar.endswith(' '):
return super().form_valid(form)
elif " http" in tempvar:
return super().form_valid(form)
elif ' ' not in tempvar:
return super().form_valid(form)
else:
return None
models.py:
class Post(models.Model):
content = models.TextField(max_length=1000)
title = models.TextField(max_length=500, default='SOME STRING') #
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
likes= models.IntegerField(default=0)
dislikes= models.IntegerField(default=0)
def __str__(self):
return (self.content[:5], self.title[:5]) #
#property
def number_of_comments(self):
return Comment.objects.filter(post_connected=self).count()
And in home.html, where the post (along with the title and content) is supposed to be shown:
<a
style="color: rgba(255, 255, 255, 0.5) !important;"
href="{% url 'post-detail' post.id %}">
<p class="mb-4">
{{ post.content }}
{{ post.title }} #
</p>
</a>
The original template I'm modifying can be found here.
Thank you so much for your help, I will be very glad to take any advice!!
Ps: I'm using Python 3.7.4
Create a forms.py file inside the app you are talking about, it should look like this:
from django import forms
from . import models
class YourFormName(forms.ModelForm):
class Meta:
model = models.your_model_name
fields = ['field1', 'field2' ,...] # Here you write the fields of your model, this fields will appear on the form where user post data
Then you call that form into your views.py so Django can render it into your template, like this:
def your_view(request, *args, **kwargs):
if request.method == 'POST':
form = forms.YourFormName(request.POST, request.FILES)
if form.is_valid():
instance = form.save(commit=False)
instance.user= request.user
instance.save()
return redirect('template.html') # To redirect if the form is valid
else:
form = forms.YourFormName()
return render(request, "template.html", {'form': form}) # The template if the form is not valid
And the last thing to do is create the template.html:
{% extends 'base.html' %}
{% block content %}
<form action="{% url 'the_url_that_renders_this_template' %}" method='POST' enctype="multipart/form-data">
{% csrf_token %}
{{ form }}
<button type="submit">Submit</button>
</form>
{% endblock content %}
If you want to take the data from DB submitted in that form, you do so with a new function in views.py:
def show_items(request, *args, **kwargs):
data = YourModelName.objects.all()
context = {
"data": data
}
return render(request, "show_items.html", context)
Then in show_items.html:
{% extends 'base.html' %}
{% block content %}
{% for item in data %}
{{item.field1}}
{{item.field2}}
...
{{The items you want to show in that template}}
{% enfor %}
{% endblock content %}
That's what you wanted to do? If not, add a further explanation on what actually you want to do

Django save inline formset from template view

Have a master-detail objects with a one-to-many relationship:
from django.db import models
class Master(models.Model):
field1 = models.CharField(max_length=100)
field2 = models.IntegerField()
class Detail(models.Model):
field3 = models.IntegerField()
field4 = models.IntegerField()
field5 = models.IntegerField()
master = models.ForeignKey(Master, on_delete=models.CASCADE)
For details, I have a ModelForm and an inline formset:
from django import forms
from .models import Master, Detail
class MasterForm(forms.Form):
field1 = forms.CharField(label='Field 1', max_length=100)
field2 = forms.IntegerField(label='Field 2')
class DetailsForm(forms.ModelForm):
class Meta:
model = Detail
exclude = ()
DetailsFormset = forms.inlineformset_factory(
Master, Detail, form=DetailsForm, extra=1)
I have a template view:
class MasterDetailsView(TemplateView):
template_name = 'app/master_detailsview.html'
def post(self, request, *args, **kwargs):
print('IN POST!')
details_formset = DetailsFormset(request.POST)
if details_formset.is_valid():
print('FORMSET VALID!')
Master.objects.get(pk=self.kwargs['pk']).save()
details_formset.save()
else:
print('ERRORS!')
print(details_formset.errors)
return HttpResponseRedirect(self.request.path_info)
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(**kwargs)
pk = self.kwargs['pk']
master_instance = Master.objects.get(pk=pk)
context['master_instance'] = master_instance
if self.request.POST:
context['details_formset'] = DetailsFormset(self.request.POST, instance=master_instance)
else:
context['details_formset'] = DetailsFormset(instance=master_instance)
return context
and the template:
{% extends 'base.html' %}
{% block contents %}
<table class="table table-bordered">
<tr>
<th>Field 1</th>
<th>Field 2</th>
</tr>
<tr>
<td>{{ master_instance.field1 }}</td>
<td>{{ master_instance.field2 }}</td>
</tr>
</table>
<hr/ >
<form action="" method="post">
{% csrf_token %}
{{ details_formset.as_p }}
<input type="submit" value="Save" />
</form>
<hr/ >
{% endblock %}
The error I get in the console:
[{'master': ['The inline value did not match the parent instance.']}]
I suppose my view is not right. I have tried getting the master record and saving it before the details formset but same error. I am not using CreateView because this is a learning project.
Try adding {{details_formset.management_form}} right under the csrf_token in templates

django 1.8 error: 'NoneType' object is not callable

Please see in picture, there is a form with 2 fields. After user entry the information and submit the form. The page will redirect to another html showing the form AND the filtered database result.
The structure of my project is 1 model with 2 classes(inputform; result), 2 html and 1 views.py.
The issue now is "'NoneType' object is not callable'. So I suspect it is because the views.py , there is something wrong. Your help is really appreciated. Thanks in advance.
url
from result.views import ResultView,InputFormView
from django.views.generic import TemplateView,FormView,ListView
urlpatterns = patterns('',
url(r'^result_list/$',ResultView.as_view(),name='result'),
url(r'^input/$',InputFormView.as_view(),name='input'),
)
views.py
from result.forms import InputForm
from result.models import Result,Input
from django.views.generic.list import ListView
from django.views.generic import FormView
....
#csrf_exempt
class InputFormView(FormView):
template_name = 'inputform.html'
form = InputForm
def get_success_url(self): /*redirect to result page with submitted form information*/
return ''.join(
[
reverse('dupont'),
'?company=',self.request.POST.get('company'),
'?region=',self.request.POST.get('region')
]
)
class ResultView(ListView):
context_object_name = 'result_list'
template_name = 'result_list.html'
def get_context_data(self, **kwargs):
context = super(ResultView, self).get_context_data(**kwargs)
return context
def get_queryset(self):
if self.request.method == 'POST':
form = InputForm(self.request.POST)
if form.is_valid():
company = form.cleaned_data['company']
region = form.cleaned_data['region']
/---Based on form entry, do the filter on the database-----/
queryset=Result.objects.filter(region=region,company=company)
sales=Result.objects.filter(queryset).aggregate(Sum('sales'))
employee=Result.objects.filter(queryset).aggregate(Sum('employee'))
departments=Result.objects.filter(queryset).aggregate(Sum('departments'))
form.save()
return render(request,'result_list.html',{'company':company},{'region':region},{'employee':employee},{'sales':sales},{'departments':departments})
else:
print form.errors
else:
form=InputForm()
return super(ResultView,self).get_queryset()
Traceback:
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\core\handlers\base.py" in get_response
132. response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\base.py" in view
71. return self.dispatch(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\base.py" in dispatch
89. return handler(request, *args, **kwargs)
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\edit.py" in get
205. form = self.get_form()
File "C:\Python27\lib\site-packages\django-1.8.3-py2.7.egg\django\views\generic\edit.py" in get_form
74. return form_class(**self.get_form_kwargs())
Exception Type: TypeError at /input/
Exception Value: 'NoneType' object is not callable
result_list.html
<div class="basicinfo"> <!--Entry Form information submitted by user-->
<table border="1" cellpadding="1">
<tr>
<td align="left">Company</td>
<td>{{ company }}</td>
</tr>
<tr>
<td align="left">Region</td>
<td>{{ region }}</td>
</tr>
</table>
{% endfor %}
</div>
<!--Showing the filtered result in database-->
<td><table border="0" cellspacing="10" cellpadding="10">
<tr><b>Sales</b></tr>
<td bgcolor="#F0F0F0"> {{sales}}</td>
</tr>
<tr><b>Employee</b></tr>
<tr>
<td bgcolor="#F0F0F0"> {{employee.employee__sum}}</td>
</tr>
<tr><b>Departments</b></tr>
<td bgcolor="#F0F0F0"> {{departments.departments__sum}}</td>
</td></table>
input.html
<div class="field">
{{ form.company.errors }}
<label for="{{ form.company.id_for_label }}">Company:</label>
{{ form.company }}
</div>
<div class="field" >
<label> Select the Region:
{{ form.region }}
{% for region in form.region.choices %}
<option value="region" name= "region" id="id_region">{{region}} </option>
{% endfor %}
</label>
</div>
Upgraded views.py based on suggestion
from result.forms import InputForm
from django.views.generic import DetailView
from django.views.generic.edit import FormView,FormMixin
from django.contrib import messages
from django.template import RequestContext
from django.shortcuts import redirect
from django.db.models import Sum,Avg
from django.views.generic.detail import MultipleObjectMixin
class InputFormView(FormMixin,DetailView):
template_name = 'inputform.html'
form = InputForm
def post(self, request, *args, **kwargs):
self.object = self.get_object()
form=self.get_form()
if form.is_valid():
return self.form_valid(form)
else:
return self.form_invalid(form)
print form.errors
def get(self, request, *args, **kwargs):
view = DupontView.as_view()
return view(request, *args, **kwargs)
def form_valid(self, form):
company = form.cleaned_data['company']
region = form.cleaned_data['region']
queryset=Result.objects.filter(company=company,region=region)
sales=Result.objects.queryset.aggregate(Sum('sales'))
employee=Result.objects.queryset.aggregate(Sum('employee'))
departments=Result.objects.queryset.aggregate(Sum('departments'))
return super(ResultView,self).form_valid(form)
def get_success_url(self):
return reverse('dupont', kwargs={'pk': self.object.pk})
class ResultView(MultipleObjectMixin,DetailView):
context_object_name = 'result_list'
template_name = 'result_list.html'
<----how can I get the submitted information and query result here from InputFormView? Is following correct?--->
def get(self, request, *args, **kwargs):
self.object = self.get_object(queryset=Result.objects.filter(company=company,region=region))
return super(Result, self).get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super(ResultView, self).get_context_data(**kwargs)
context['InputFormView']= self.object
return context
def get_queryset(self):
return self.object. ? .all() <---what to put here? are they "sales","departments","employee" from database filtered result together with the form data-"region" and "company"?
please take a look at these files, maybe they will be helpful to you.
https://github.com/EchoUA/Tweaks-and-Hacks/tree/master/miaomiao
in views.py, the context is one dictionary !
return render(request,'result_list.html',{'company':company,'region':region, 'employee':employee, 'sales':sales, 'departments':departments})
<div class="basicinfo"> <!--Entry Form information submitted by user-->
<table border="1" cellpadding="1">
<tr>
<td align="left">Company</td>
<td>{{company}}</td>
</tr>
<tr>
<td align="left">Region</td>
<td>{{region}}</td>
</tr>
</table>
<!--Showing the filtered result in database-->
<td><table border="0" cellspacing="10" cellpadding="10">
<tr><b>Sales</b></tr>
<td bgcolor="#F0F0F0"> {{sales}}</td>
</tr>
<tr><b>Employee</b></tr>
<tr>
<td bgcolor="#F0F0F0"> {{employee}}</td>
</tr>
<tr><b>Departments</b></tr>
<td bgcolor="#F0F0F0"> {{departments}}</td>
</td></table>
You are writing way too much code for a simple form.
Create a simple form; which is just a search for your second view:
class SearchForm(forms.Form):
company = forms.CharField()
region = forms.CharField()
Create a view to display the form:
def search_form(request):
form = SearchForm(request.GET)
if form.is_valid():
company = form.cleaned_data['company']
region = form.cleaned_data['region']
url = '{}?company={}&region={}'.format(reverse('result-list'), company, region)
return redirect(url)
return render(request, 'form.html', {'form': form})
Create a view to display the results:
def show_results(request):
company = request.GET.get('company')
region = request.GET.get('region')
if company is None or region is None:
return redirect('input')
# Your normal logic here
queryset=Result.objects.filter(company=company,region=region)
sales=Result.objects.aggregate(Sum('sales'))
employee=Result.objects.aggregate(Sum('employee'))
departments=Result.objects.aggregate(Sum('departments'))
return render(request, 'results.html', {'sales': sales,
'employee': employee,
'departments': departments,
'queryset': queryset})
If I understand correctly, when you send a GET request to
127.0.0.1:8000/input/
then you get the error. Do you get the same error when you send a post request to that URL? Try changing input.html to this:
<div class="field">
<!-- Check if the errors exist first before calling them.
If youre sending a GET request, then form errors will
probably not exist. -->
{% if form.company.errors %}
{{ form.company.errors }}
<label for="{{ form.company.id_for_label }}">Company:</label>
{% endif %}
{{ form.company }}
</div>
<div class="field" >
<label> Select the Region:
{{ form.region }}
<!-- over here, are you sure form.region.choices exists? Can you
post your model / model form so that we can verify that
form.region.choices exists? -->
{% for region in form.region.choices %}
<option value="region" name= "region" id="id_region">{{region}} </option>
{% endfor %}
</label>
</div>
Let me know if you still get the error after using this code. In the code above, I left a comment mentioning to verify that form.region.choices exists. Can you upload your model and model form so that we can verify that form.region.choices exists?

"this field is required" error in file upload form?

I am trying to do a form with file uploading. I got "this field is required" even though I choose a file in the form. Below is my code.
It works once before, I don't why it doesn't work suddenly.Thanks in advance.
Model
from django.db import models
from django.contrib.auth.models import User
from time import time
def get_upload_file_name(instance, filename):
return "uploaded_files/%s_%s" % (str(time()).replace('.', '_'), filename)
# Create your models here.
class UserProfile(models.Model):
user = models.OneToOneField(User)
contact_number = models.CharField(max_length=10)
tag_id = models.CharField(max_length=20)
layout = models.FileField(upload_to=get_upload_file_name)
User.profile = property(lambda u: UserProfile.objects.get_or_create(user=u)[0])
Form
from django import forms
from models import UserProfile
class UserProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
fields = ('contact_number','tag_id', 'layout')
View
#login_required
def user_profile(request):
if request.method == 'POST' and request.is_ajax():
form = UserProfileForm(request.POST, request.FILES,instance=request.user.profile)
if form.is_valid():
form.save()
#return HttpResponseRedirect('/accounts/loggedin')
return HttpResponse("Update success")
else:
#return HttpResponseRedirect('/accounts/loggedin')
return HttpResponse("Update error")
else:
user = request.user
profile = user.profile
form = UserProfileForm(instance=profile)
args = {}
args.update(csrf(request))
args['form'] = form
args['full_name'] = request.user.username
return render_to_response('profile.html', args)
profile.html
<div align = "center">
<h2 >Profile</h2>
<form id="profile_form" method="POST" action="/accounts/profile/" enctype="multipart/form-data">
{% csrf_token %}
<table>
<tbody>
<tr>
<td>Name:</td>
<td>{{full_name}}</td>
</tr>
<tr>
<td>Tag ID</td>
<td>{{form.tag_id}}</td>
</tr>
<tr>
<td>Contact number</td>
<td>{{form.contact_number}}</td>
</tr>
<tr>
<td>Layout</td>
<td>{{form.layout}}</td>
</tr>
</tbody>
</table>
<input type="submit" id="update" value="Update" />
</form>
<DIV id="saved"></DIV>
</div>

Categories

Resources