I'm running some tests for my app 'ads', but when I try to test the CreateView it fails with the following message:
AssertionError: 'just a test' != 'New title'
Here's the test:
class AdTests(TestCase):
def setUp(self):
self.user = get_user_model().objects.create_user(
username='test_user',
email='test#email.com',
password='secret'
)
self.ad = Ad.objects.create(
title='just a test',
text='Ehy',
owner=self.user
)
def test_ad_create_view(self):
response = self.client.post(reverse('ads:ad_create'), {
'title': 'New title',
'text': 'New text',
'owner': self.user.id,
})
self.assertEqual(response.status_code, 302)
self.assertEqual(Ad.objects.last().title, 'New title')
self.assertEqual(Ad.objects.last().text, 'New text')
So it could be that the test fails in creating a new ad, and then it compares the fields with the first ad in the setUp method.
I upload the rest of the code if it can help:
urls.py
from django.urls import path, reverse_lazy
from . import views
app_name='ads'
urlpatterns = [
path('', views.AdListView.as_view(), name='all'),
path('ad/<int:pk>', views.AdDetailView.as_view(), name='ad_detail'),
path('ad/create',
views.AdCreateView.as_view(success_url=reverse_lazy('ads:all')), name='ad_create'),
...
]
models.py
class Ad(models.Model) :
title = models.CharField(
max_length=200,
validators=[MinLengthValidator(2, "Title must be greater than 2 characters")]
)
price = models.DecimalField(max_digits=7, decimal_places=2, null=True)
text = models.TextField()
"""We use AUTH_USER_MODEL (which has a default value if it is not specified in settings.py) to create a Foreign Key relationship between the Ad model
and a django built-in User model"""
owner = models.ForeignKey(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
comments = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Comment', related_name='comments_owned')
picture = models.BinaryField(null=True, editable=True)
tags = TaggableManager(blank=True)
content_type = models.CharField(max_length=256, null=True, help_text='The MIMEType of the file')
favorites = models.ManyToManyField(settings.AUTH_USER_MODEL, through='Fav', related_name='favorite_ads')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
views.py
class AdCreateView(LoginRequiredMixin, View):
template_name = 'ads/ad_form.html'
success_url = reverse_lazy('ads:all')
def get(self, request, pk=None):
form = CreateForm()
ctx = {'form': form}
return render(request, self.template_name, ctx)
# Pull data
def post(self, request, pk=None):
form = CreateForm(request.POST, request.FILES or None)
if not form.is_valid():
ctx = {'form': form}
return render(request, self.template_name, ctx)
pic = form.save(commit=False)
pic.owner = self.request.user
pic.save()
form.save_m2m()
return redirect(self.success_url)
forms.py (the view uses it especially to check and save the image)
class CreateForm(forms.ModelForm):
max_upload_limit = 2 * 1024 * 1024
max_upload_limit_text = naturalsize(max_upload_limit)
# Call this 'picture' so it gets copied from the form to the in-memory model
# It will not be the "bytes", it will be the "InMemoryUploadedFile"
# because we need to pull out things like content_type
picture = forms.FileField(required=False, label='File to Upload <= ' + max_upload_limit_text)
upload_field_name = 'picture'
class Meta:
model = Ad
fields = ['title', 'text', 'price', 'picture', 'tags']
# Check if the size of the picture is less than the one specified (see above).
def clean(self):
cleaned_data = super().clean()
pic = cleaned_data.get('picture')
if pic is None:
return
if len(pic) > self.max_upload_limit:
self.add_error('picture', "File must be < " + self.max_upload_limit_text + " bytes")
# Convert uploaded File object to a picture
def save(self, commit=True):
instance = super(CreateForm, self).save(commit=False)
# We only need to adjust picture if it is a freshly uploaded file
f = instance.picture # Make a copy
if isinstance(f, InMemoryUploadedFile): # Extract data from the form to the model
bytearr = f.read()
instance.content_type = f.content_type
instance.picture = bytearr # Overwrite with the actual image data
if commit:
instance.save()
self.save_m2m()
return instance
I hope it is useful, thanks in advance!
According to Django Doc
Create View:
A view that displays a form for creating an object, redisplaying the form with validation errors (if there are any) and saving the object.
This is not a Valid way to do create View based on my experience. Check the doc Doc here.
if i understand what you are talking about You want to submit Ad Model using Create View, if you want to submit it in form You can something like this:
from django.views.generic import CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.urls import reverse_lazy,
class PostCreativeView(LoginRequiredMixin, CreateView):
model = #Your Model
fields = [#Fields of the model You want to submit]
template_name = #html template you want to submit the form
success_url = reverse_lazy(#url for redirected user when the form is submitted)
def form_valid(self, form):
form.instance.user = self.request.user
return super (PostCreativeView, self).form_valid(form)
in the form template you can add:
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
for styling you can follow this: Answer
Related
I have a comment section in django blog and there are two forms one is for comment another is for reply to the comment but the comment form is working fine and reply form doesn't work! i was trying to do but getting error... IntegrityError at /page/9/
FOREIGN KEY constraint failed...
appreciate to your help :)
Thank you.
views.py
class PostDetailView(DetailView):
model = Post
template_name = "post_detail.html"
context_object_name = 'post'
form = CommentForm()
def get_object(self):
obj = super().get_object()
if self.request.user.is_authenticated:
PostView.objects.get_or_create(
user=self.request.user,
post=obj
)
return obj
def get_context_data(self, **kwargs):
category_count = get_category_count()
most_recent = Post.objects.order_by('-timestamp')[:3]
context = super().get_context_data(**kwargs)
context['most_recent'] = most_recent
context['page_request_var'] = "page"
context['category_count'] = category_count
context['form'] = self.form
return context
def post(self, request, *args, **kwargs):
form = CommentForm(request.POST)
form = ReplyForm(request.POST)# how to work with this form like above from
if form.is_valid():
post = self.get_object()
form.instance.user = request.user
form.instance.post = post
form.save()
return redirect(reverse("post-detail", kwargs={
'pk': post.pk
}))
models.py
class Reply(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
content = models.TextField()
comment = models.ForeignKey('Comment', related_name='replies',default=False, null=True,
on_delete=models.CASCADE)
def __str__(self):
return self.content
class Comment(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
timestamp = models.DateTimeField(auto_now_add=True)
content = models.TextField()
post = models.ForeignKey('Post', related_name='comments', default=False,
on_delete=models.CASCADE)
def __str__(self):
return self.content
You might find it easier if you did not struggle with trying to persuade a Class-based view to do what it was not intended to do, and instead used a plain old Function-based view.
Here is a two-form view. The code has been refactored into what I regard as a better pattern, to validate both forms and redisplay if anything is wrong at the top, and then you just do the actual work to create and save the objects at the bottom.
def receive_uncoated( request): #Function based view
# let's put form instantiation in one place not two, and reverse the usual test. This
# makes for a much nicer layout with actions not sandwiched by "boilerplate"
# note any([ ]) forces invocation of both .is_valid() methods
# so errors in second form get shown even in presence of errors in first
args = [request.POST, ] if request.method == "POST" else []
batchform = CreateUncWaferBatchForm( *args )
po_form = CreateUncWaferPOForm( *args, prefix='po')
if request.method != "POST" or any(
[ not batchform.is_valid(), not po_form.is_valid() ]):
return render(request, 'wafers/receive_uncoated.html', # can get this out of the way at the top
{'batchform': batchform,
'po_form': po_form,
})
#POST, everything is valid, do the work
# create and save some objects based on the validated forms ...
return redirect( 'wafers:ok' )
I am a noob in django and am not able to figure out the issue in my code. Basically I am trying to upload some images to my server using a form. Whenever I save the form, it is only taking the default image specified in my model, not the images I uploaded in my form.
print(request.Files) before calling form.is_valid() is giving output as:
<MultiValueDict: {'id_image01': [<InMemoryUploadedFile: image01.jpg (image/jpeg)>], 'id_image02': [<InMemoryUploadedFile: image02.jpg (image/jpeg)>], 'id_image03': [<InMemoryUploadedFile: image04.jpg (image/jpeg)>], 'id_image04': [<InMemoryUploadedFile: image07.jpg (image/jpeg)>]}>
which I presume says that the image is correctly loaded in the memory.
My code goes like this:
views.py
def create_puzzle(request):
if request.method == 'POST':
print(request.FILES)
form = DocumentForm(request.POST, request.FILES)
if form.is_valid():
puzzleImages= form.save(commit=False)
puzzleImages.username= request.user.username
puzzleImages.save()
return redirect('/puzzle/index.html')
else:
form = DocumentForm()
return render(request, 'puzzle/create_puzzle.html', {
'form': form
})
my Forms.py
class DocumentForm(forms.ModelForm):
class Meta:
model = Document
fields = ('birthday_message', 'video_url', 'image01',
'image02', 'image03','image04',
'image05', 'image06', 'image07',
'image08', 'image09', 'image10')
captcha = ReCaptchaField(
public_key='###########',
private_key='###########',
)
my models.py
class Document(models.Model):
description = models.CharField(max_length=255, blank=True)
image01 = models.ImageField(default='default/image01.png', upload_to=user_directory_path)
image02 = models.ImageField(default='default/image02.png', upload_to=user_directory_path)
image03 = models.ImageField(default='default/image03.png', upload_to=user_directory_path)
image04 = models.ImageField(default='default/image04.png', upload_to=user_directory_path)
image05 = models.ImageField(default='default/image05.png', upload_to=user_directory_path)
image06 = models.ImageField(default='default/image06.png', upload_to=user_directory_path)
image07 = models.ImageField(default='default/image07.png', upload_to=user_directory_path)
image08 = models.ImageField(default='default/image08.png', upload_to=user_directory_path)
image09 = models.ImageField(default='default/image09.png', upload_to=user_directory_path)
image10 = models.ImageField(default='default/image10.png', upload_to=user_directory_path)
username = models.CharField(max_length=255, blank=False)
birthday_message=models.CharField(default='Happy Birthday Special One!!!', max_length=500)
video_url=models.CharField(default='https://www.youtube.com/watch?v=A9jl1yLURp4', max_length=100)
uploaded_at = models.DateTimeField(auto_now_add=True)
def save(self, *args, **kwargs):
#print (self.image01)
#print(self.birthday_message)
if not self.id:
self.image01 = self.compressImage(self.image01, "image01")
self.image02 = self.compressImage(self.image02, "image02")
self.image03 = self.compressImage(self.image03, "image03")
self.image04 = self.compressImage(self.image04, "image04")
self.image05 = self.compressImage(self.image05, "image05")
self.image06 = self.compressImage(self.image06, "image06")
self.image07 = self.compressImage(self.image07, "image07")
self.image08 = self.compressImage(self.image08, "image08")
self.image09 = self.compressImage(self.image09, "image09")
self.image10 = self.compressImage(self.image10, "image10")
super(Document, self).save(*args, **kwargs)
Thank you for your help!
Please add below line of code in your template
<form enctype="multipart/form-data" method="post">
-----
----
----
</form>
I found out the cause of the issue. I wanted to render form fields manually and was using to get the files. It would pass the text inputs normally but when it came to files, it would not validate them. So, instead of having a tag such as:
<input name="id_image03" type="file" class="form-control" id="id_image03">
I did:
{{ form.image03 }}
That was it!
I can't get files to upload through a CreateView using inline formset.
Ideally, it would be multiple files similar to how it behaves in the admin page, but at this point, I'm trying to get at least one up. In the following example, one Workshop should be able to have multiple files.
When uploading, everything saves except the file of course
models.py
...
class Workshop (models.Model):
title = models.CharField(max_length=120)
created_by = models.ForeignKey(User)
slug = models.SlugField(blank=True, null=True, unique=True)
def __str__(self):
return self.title
...
def upload_workshop_file_loc(instance, filename):
slug = instance.workshop.slug
if not slug:
slug = unique_slug_generator(instance.workshop)
location = "workshop/{}/".format(slug)
return location + filename
class WorkshopFile(models.Model):
workshop = models.ForeignKey(Workshop, related_name='files', on_delete=models.CASCADE)
name = models.CharField()
file = models.FileField(
upload_to=upload_workshop_file_loc,
null=True,
validators=[FileExtensionValidator
(allowed_extensions=['pdf', 'ppt'])]
)
def __str__(self):
return str(self.file.name)
...
forms.py
from django import forms
from .models import Workshop, WorkshopFile
from django.forms.models import inlineformset_factory
class AddWorkshopForm(forms.ModelForm):
class Meta:
model = Workshop
exclude = []
FileFormSet = inlineformset_factory(Workshop,
WorkshopFile,
fields=['workshop','name', 'file'],
exclude=[],
extra=1,
can_delete=True
)
Most likely the culprit
views.py
...
class AddWorkshopView(LoginRequiredMixin, CreateView):
model = Workshop
form_class = AddWorkshopForm
template_name = "modules/add-workshop.html"
success_url = "/modules/workshop-list/"
def post(self, request, *args, **kwargs):
form = AddWorkshopForm(request.POST, request.FILES)
workshop = form.save(commit=False)
workshop.save()
workshop.created_by = request.user
return redirect('modules:workshop', workshop.slug)
def get_context_data(self, **kwargs):
data = super(AddWorkshopView, self).get_context_data(**kwargs)
if self.request.POST:
data['files'] = FileFormSet(self.request.POST)
else:
data['files'] = FileFormSet()
return data
def form_valid(self, form):
context = self.get_context_data()
files = context['files']
with transaction.atomic():
form.instance.created_by = self.request.user
form.instance.updated_by = self.request.user
self.object = form.save()
if files.is_valid():
files.instance = self.object
files.save()
return super(AddWorkshopView, self).form_valid(form)
...
add-workshop.html
...
<div>
<form method="post" action='' enctype='multipart/form-data'>
{% csrf_token %}
{{ form | crispy }}
<hr/>
<div>
{{ files | crispy }}
</div>
<input type="submit" class="btn btn-primary btn-md float-left" value="Save" />
</form>
</div>
...
You should not override post method - it's calling form_valid behind the scene, so it's not actually handling form. Another thing is that your FileFormSet is not getting request.FILES - that's why form for files is not processing it.
views.py:
class AddWorkshopView(LoginRequiredMixin, CreateView):
model = Workshop
form_class = AddWorkshopForm
template_name = "modules/add-workshop.html"
success_url = "/modules/workshop-list/"
def get_context_data(self, **kwargs):
data = super(AddWorkshopView, self).get_context_data(**kwargs)
if self.request.POST:
data['files'] = FileFormSet(self.request.POST, self.request.FILES)
else:
data['files'] = FileFormSet()
return data
def form_valid(self, form):
context = self.get_context_data()
files = context['files']
with transaction.atomic():
form.instance.created_by = self.request.user
form.instance.updated_by = self.request.user
self.object = form.save()
if files.is_valid():
files.instance = self.object
files.save()
return super(AddWorkshopView, self).form_valid(form)
In my case, upload the images to s3 via CreateView and without Formset. I hope this will help someone who looking for this kinda scenario.
from bootstrap_modal_forms.generic import (BSModalCreateView)
from vcweb.settings import base
from .forms import InputForm
from utils import upload_to_s3 #global method for upload files to s3
from datetime import datetime
from django.utils.timezone import get_current_timezone
curdatetime = datetime.now(tz=get_current_timezone())
curdatetime=(str(curdatetime)).replace('-','_').replace('+','_').replace('.','_')
curdatetime=curdatetime.replace(':','_').replace(' ','_')
class InputCreateView(BSModalCreateView):
model = Input_Product
form_class = InputForm
template_name = 'inputs/create_product.html'
success_message = 'Success: Input Product is created.'
success_url = reverse_lazy('input_product_list')
def form_valid(self, form):
form.instance.created_by = self.request.user
form.instance.updated_by = self.request.user
# get the image by using request.FILES.get
filepath = self.request.FILES.get('product_Image', False)
user_id = self.request.user.id
#generate filename along with datetime string
key = base.INPUT_PRODUCT_IMAGE_FOLDER+'/images/' + str(user_id) + '/productimages/' + curdatetime + '.png'
if filepath == False:
print(filepath)
else: #if file exists send the those file and s3 details to upload_to_s3 to upload the data into s3
s3status = upload_to_s3(base.S3_KEY, base.S3_SECRET, filepath, base.S3_BUCKET, key, callback=None, md5=None,
reduced_redundancy=False, content_type=None)
# after upload the image, set the filepath value to column(file or image field variable)
form.instance.product_Image=key
return super().form_valid(form)
Create utils.py file and declare upload_to_s3 method
import os
import boot
from boto.s3.key import Key
def upload_to_s3(aws_access_key_id, aws_secret_access_key, file, bucket, key,
callback=None, md5=None,
reduced_redundancy=False, content_type=None):
try:
size = os.fstat(file.fileno()).st_size
except:
# Not all file objects implement fileno(),
# so we fall back on this
file.seek(0, os.SEEK_END)
size = file.tell()
conn = boto.connect_s3(aws_access_key_id, aws_secret_access_key)
bucket = conn.get_bucket(bucket, validate=True)
k = Key(bucket)
k.key = key
if content_type:
k.set_metadata('Content-Type', content_type)
sent = k.set_contents_from_file(file, cb=callback, md5=md5,
reduced_redundancy=reduced_redundancy, rewind=True)
# Rewind for later use
file.seek(0)
if sent == size:
return True
return False
Can someone help me with fixing Django ModelForm?
This particular code can add new item to database as expected, but when I'm trying to edit db record - It just add new record, instead of updating old. I'm quite new in Django framework.
views.py:
def manage(request, item_id = None):
t = get_object_or_404(Hardware, id=item_id) if item_id else None
form = Manage(request.POST or None, instance=t)
if t:
if form.is_valid():
#form.save()
hostname = form.cleaned_data['hostname']
cpu = form.cleaned_data['cpu']
os = form.cleaned_data['os']
ram = form.cleaned_data['ram_total']
storage = form.cleaned_data['storage']
hostdata = Hardware(
hostname=hostname,
cpu=cpu,
ram_total=ram,
os=os,
storage=storage,
lock_state=t.lock_state, # because in edit operation we shouldn't change it.
lock_date=t.lock_date, # because in edit operation we shouldn't change it.
locked_by=t.locked_by) # because in edit operation we shouldn't change it.
hostdata.save()
return HttpResponseRedirect(reverse('main:index'))
elif not t:
if form.is_valid():
hostname = form.cleaned_data['hostname']
cpu = form.cleaned_data['cpu']
os = form.cleaned_data['os']
ram = form.cleaned_data['ram_total']
storage = form.cleaned_data['storage']
current_user = request.user
user = User.objects.get(id=current_user.id)
hostdata = Hardware(
hostname=hostname,
cpu=cpu,
ram_total=ram,
os=os,
storage=storage,
lock_state=0,
lock_date=datetime.datetime.now(),
locked_by=user)
hostdata.save()
return HttpResponseRedirect(reverse('main:index'))
return render(request, 'hardware/edit.html', {'form': form})
models.py:
class Hardware(models.Model):
hostname = models.CharField(max_length=255, default=None)
os = models.CharField(max_length=255, default=None)
cpu = models.CharField(max_length=255, default=None)
ram_total = models.CharField(max_length=255, default=None)
storage = models.CharField(max_length=255, default=None)
lock_state = models.BooleanField(default=0)
locked_by = models.ForeignKey(User)
lock_date = models.DateTimeField(default=None)
alive = models.BooleanField(default=0)
class Meta:
db_table = "hardware"
def __str__(self):
return self.hostname
forms.py:
class Manage(forms.ModelForm):
class Meta:
model = Hardware
fields = ['hostname', 'os', 'cpu', 'ram_total', 'storage']
urls.py:
url(r'^manage/new/$', views.manage, name='add'),
url(r'^manage/edit/(?P<item_id>[0-9]+)/$', views.manage, name='edit')
template:
<form action="" method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save!" />
</form>
You already retrieved the instance t in the first line of your view. The code below will always create a new instance (unless you specify the pk parameter):
hostdata = Hardware(...)
hostdata.save()
Simply do this instead:
if t:
if form.is_valid():
t.hostname = form.cleaned_data['hostname']
t.cpu = form.cleaned_data['cpu']
....
t.save()
However, you really should rely on the save method provided by the ModelForm as the other answers suggested. Here's an example:
def manage(request, item_id=None):
t = get_object_or_404(Hardware, id=item_id) if item_id else None
# if t is None, a new object will be created in form.save()
# if t is an instance of Hardware, t will be updated in form.save()
form = Manage(request.POST, instance=t)
if form.is_valid():
form.save()
return HttpResponseRedirect(reverse('main:index')
return render(request, 'hardware/edit.html', {'form': form})
You also specified fields in your form:
fields = ['hostname', 'os', 'cpu', 'ram_total', 'storage']
These are the fields which will be set or updated when you call form.save().
I think something like this - using update_fields - should work:
def manage(request, item_id = None):
t = get_object_or_404(Hardware, id=item_id)
form = Manage(request.POST or None, instance=t)
if t:
if form.is_valid():
#form.save()
t.hostname = form.cleaned_data['hostname']
t.cpu = form.cleaned_data['cpu']
t.os = form.cleaned_data['os']
t.ram = form.cleaned_data['ram_total']
t.storage = form.cleaned_data['storage']
t.save(update_fields=['hostname', 'cpu', 'os','ram','storage'])
return HttpResponseRedirect(reverse('main:index'))
........
Try Class Based View, which in it's simplest looks like:
from django.views import generic
class HardwareEditView(generic.UpdateView):
template_name = "hardware.html"
form_class = Manage
You will have to add get_absolute_url to the model.
Generic class based views are exactly for this standard create/update/view common tasks.
I am using django-selectable and having trouble saving the "id" ('autocomplete_1') which represents the id for the category --- from the template.
models.py
class Category(models.Model):
cat_no = models.IntegerField(null=True, blank=True)
cat_txt = models.CharField(max_length=45)
def __unicode__(self):
return self.cat_txt
class Cattest(models.Model):
category = models.ForeignKey(Category)
info = models.CharField(max_length=35, blank=True)
lookups.py
class CategoryLookup(ModelLookup):
model = Category
search_fields = ('cat_txt__icontains', )
forms.py
class CategoryForm(forms.Form):
autocomplete = forms.CharField(
label='Type the name of a category (AutoCompleteWidget)',
widget=selectable.AutoCompleteWidget(CategoryLookup),
required=False,
)
autocompleteselect = selectable.AutoCompleteSelectField(
lookup_class=CategoryLookup,
label='Select a category (AutoCompleteField)',
required=False,
)
class CattestForm(forms.Form):
#model = cattest
#fields = ('category', 'info')
autocomplete = forms.CharField(
label='Type the name of a category (AutoCompleteSelectWidget)',
widget=selectable.AutoCompleteSelectWidget(CategoryLookup),
required=False,
)
info = forms.CharField(max_length=35, label="Information")
views.py
def cattest(request):
if request.method == 'POST':
form = CattestForm(request.POST)
if form.is_valid():
cattest = Cattest.objects.create(
category=form.cleaned_data['autocomplete_1'],
info=form.cleaned_data['info'],
)
# Always redirect after a POST
return http.HttpResponseRedirect('/bsmain/login_customer')
else:
if request.GET:
form = CattestForm(initial=request.GET)
else:
form = CattestForm()
return render_to_response('bsmain/form.html', {'form': form}, context_instance=RequestContext(request))
Traceback:
KeyError at /bsmain/cattest/
'autocomplete_1'
Request Method: POST
Request URL: http://127.0.0.1:8000/bsmain/cattest/
Django Version: 1.3.1
Exception Type: KeyError
Exception Value:
'autocomplete_1'
Exception Location: /home/bill/workspace/boatsite/../boatsite/bsmain/views.py in cattest, line 64
Python Executable: /usr/bin/python
Python Version: 2.6.5
Request information
GET No GET data
POST Variable Value
info u'44# Bruce'
csrfmiddlewaretoken u'9ffe49bd68be04087521e71e86a5bec0'
autocomplete_1 u'10'
autocomplete_0 u'Anchors'
The form cleaned_data dictionary is populated based on the field names. You should access the data from form.cleaned_data['autocomplete'].
Edit:
This would probably be easier by using a ModelForm:
class CattestForm(forms.ModelForm):
class Meta:
model = Cattest
fields = ('category', 'info', )
widgets = {
'category': selectable.AutoCompleteSelectWidget(CategoryLookup)
}
def cattest(request):
if request.method == 'POST':
form = CattestForm(request.POST)
if form.is_valid():
cattest = form.save()
# Always redirect after a POST
return http.HttpResponseRedirect('/bsmain/login_customer')
else:
initial = request.GET or None
form = CattestForm(initial=initial)
return render_to_response('bsmain/form.html', {'form': form}, context_instance=RequestContext(request))