I'm trying to use django's FormPreview but can't get it to work properly. Here's my code:
models.py
class jobpost(models.Model):
CONTENT_CHANNELS = (
('Full Time','Full Time'),
('Part Time','Part Time'),
('Contract','Contract'),
)
user = models.ForeignKey(User)
job_id = models.AutoField(primary_key=True)
#user = models.ForeignKey(User, editable = False)
job_type = models.CharField(max_length=255,null=True, choices=CONTENT_CHANNELS,default='Full Time')
job_location = models.CharField(max_length=255,null=True)
job_title = models.CharField(max_length=255,null=True)
job_description = models.TextField(null=True)
def __unicode__(self):
#return self.user
return self.job_location
return self.job_type
return self.job_title
return self.job_description
admin.site.register(jobpost)
class jobpostForm(ModelForm):
class Meta:
model = jobpost
fields = ('user','job_type','job_location','job_title','job_description')
widgets = {
'job_type':RadioSelect(),
'job_location':TextInput(attrs={'size':'70'}),
'job_description':Textarea(attrs={'cols':200, 'rows':10}),
}
def __init__(self, *args, **kwargs):
self.helper = FormHelper()
self.helper.form_class = 'horizontal-form'
self.helper.form_id = 'id-jobpostform'
self.helper.form_class = 'blueForms'
self.helper.form_method = 'post'
#self.helper.form_action = '/'
self.helper.add_input(Submit('submit_addcontent', 'Submit'))
super(jobpostForm, self).__init__(*args, **kwargs)
views.py
def main_page(request):
"""
If users are authenticated, direct them to the main page. Otherwise, take
them to the login page.
"""
if request.method == 'POST':
form = jobpostForm(request.POST)
if form.is_valid():
form.save()
return HttpResponseRedirect('/thanks/')
else:
form = jobpostForm()
c = {}
c.update(csrf(request))
return render_to_response('portal/job_post.html',{'form':form},context_instance=RequestContext(request))
preview.py
class SomeModelFormPreview(FormPreview):
form_template = 'portal/job_post.html'
preview_template = 'portal/preview.html'
def done(self, request, cleaned_data):
f = self.form(request.POST)
f.save()
pdb.set_trace()
print "done"
# Do something with the cleaned_data, then redirect
# to a "success" page.
return HttpResponseRedirect('/form/success')
job_post.html
<form action = "" method = "POST" enctype="multipart/form-data" class="blueForms" id="id-jobpostform">
{% csrf_token %}
{% crispy form %}
<input name="submit" type="submit" value="Post" >
urls.py
(r'^$', main_page),
(r'^post/$', SomeModelFormPreview(jobpostForm)),
When i submit the form it goes to the / home page and submits the info. I want to first prview the form and then submit..plz tell me what i am missing or doing wrong.
Related
can you help me?
I can't fix problem: my don't show error validation
when I write not unique slug at form -> no error at form
I think problem at use def post() or return redirect after validations form.
I try many different solutions but nothing helps.
Maybe you should use a non-standard way to report an error?
models.py
class ShortUrl(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name='Автор URL', null=True)
url = models.CharField('Ссылка', max_length=200)
slug = models.SlugField('Короткое имя ссылки', unique=True, max_length=20)
def __str__(self):
#return self.slug
return f"Короткая ссылка: {self.user} >> {self.slug}"
class Meta:
verbose_name = 'Ссылка'
verbose_name_plural = 'Ссылки
forms.py
class ShortURLForm(forms.ModelForm):
slug = forms.SlugField(
label='Название URL',
required=True,
widget=forms.TextInput(attrs={'placeholder': 'Укажите уникальный URL'})
)
url = forms.CharField(
label='Ссылка',
required=True,
widget=forms.TextInput(attrs={'placeholder': 'Ссылка которую нужно сократить'})
)
class Meta:
model = ShortUrl
fields = ['user', 'url', 'slug']
widgets = {'user': forms.HiddenInput()}
views.py
class ShortURLPage(LoginRequiredMixin, ListView):
model = ShortUrl
template_name = 'main/shorts.html'
context_object_name = 'shorts'
def get_context_data(self, *, object_list=None, **kwargs):
ctx = super(ShortURLPage, self).get_context_data(**kwargs)
ctx['form'] = ShortURLForm()
userurls = ShortUrl.objects.filter(user=self.request.user)
ctx['shorts'] = userurls
ctx['title'] = 'Добавление ссылок'
return ctx
def post(self, request, *args, **kwargs):
post = request.POST.copy()
post['user'] = request.user
request.POST = post
form = ShortURLForm(request.POST)
if form.is_valid():
slug = form.cleaned_data['slug']
url = form.cleaned_data['url']
form.save()
return redirect('shorts')
shorts.html
<form method="post" class="form">
{% csrf_token %}
{{ form }}
<button class="button" type="submit">Создать ссылку</button>
</form>
urls.py
urlpatterns = [
path('', views.homepage, name='home'),
path('about/', views.about, name='about'),
path('shorts/', views.ShortURLPage.as_view(), name='shorts'),
path('shorts/<str:slug>/', views.urlRedirect, name='redirect'),
]
Ok, you're not so far away with accomplishing what you want.
Generally your post method should look like this:
def post(self, request, *args, **kwargs):
post = request.POST.copy()
post['user'] = request.user
request.POST = post
form = ShortURLForm(request.POST)
if form.is_valid():
slug = form.cleaned_data['slug']
url = form.cleaned_data['url']
form.save()
else:
context = {
'form': form,
}
return render(
request,
self.template_name,
context,
)
return redirect('shorts')
Then, you should write your shorts.html template like this:
<form method="post" class="form">
{% csrf_token %}
{{ form.non_field_errors }}
{{ form.errors }}
{{ form }}
<button class="button" type="submit">Создать ссылку</button>
</form>
I don't know why my form is invalid. Despite everything seems to be normal. I am not getting any error. sending you screenshot of models.py
Here is my forms.py
class LeadForm(forms.ModelForm):
product_queryset = []
product_name = forms.MultipleChoiceField(choices=product_queryset, required=False)
contact = PhoneNumberField()
def __init__(self, *args, **kwargs):
super(LeadForm, self).__init__(*args, **kwargs)
self.fields["product_name"].choices = [(pro.get('id'), pro.get('name')) for pro in
Products.objects.all().values('id', 'name')]
class Meta:
model = Lead
exclude = ('created_at','created_by')
widgets = {
'date_of_enquiry': DateInput(attrs={'type': 'date'})
}
Here is my views.py
def create_lead(request):
u = User.objects.get(username=request.user.get_username())
if request.method == 'POST':
print(request.POST)
# form = LeadForm()
form = LeadForm(request.POST)
if form.is_valid():
print('inside valid')
form.save(commit=True)
form.created_by = u
form.save()
form = LeadForm()
context = {"form": form}
return render(request, 'create_lead.html', context)
You should render the errors you are getting, to do that you need to send to template:
def create_lead(request):
form = LeadForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
instance = form.save(commit=False)
instance.created_by = request.user
instance.save()
return redirect('/sucess_url')
context = {"form": form}
return render(request, 'create_lead.html', context)
And render the errors in template:
{% for field in form %}
{{ field.errors }}
{% endfor %}
More information can be found in documentation regarding form error rendering.
Probably you should remove the __init__ method from Form class, instead add a __str__ method in Product model:
class Product(models.Model):
# rest of the code
def __str__(self):
return self.name
Please do in your forms.py
class Meta:
model = Lead
exclude = ('created_at','created_by')
fields = ('product_name', [and all your fields which you want to include])
widgets = {
'date_of_enquiry': DateInput(attrs={'type': 'date'})
}
I am creating an image upload function with django.
However, it is not uploaded.
I don't know the code mistake, so I want to tell you.
I tried variously, but if I specify default for imagefiled,
default will be applied.
#form
class RecordCreateForm(BaseModelForm):
class Meta:
model = URC
fields = ('image','UPRC','URN',)
def __init__(self, *args, **kwargs):
user = kwargs.pop('user')
super(RecordCreateForm,self).__init__(*args, **kwargs)
self.fields['URN'].queryset = UPRM.objects.filter(user=user)
#view
class RecordCreate(CreateView):
model = URC
form_class = RecordCreateForm
template_name = 'records/urcform.html'
success_url = reverse_lazy('person:home')
def get_form_kwargs(self):
kwargs = super(RecordCreate, self).get_form_kwargs()
# get users, note: you can access request using: self.request
kwargs['user'] = self.request.user
return kwargs
def form_valid(self, form):
user = self.request.user
form.instance.user = user
form.instance.group = belong.objects.get(user=user).group
return super().form_valid(form)
#model
def get_upload_path(instance, filename):
n = datetime.now()
prefix = "records/"
ymd='/'.join([n.strftime('%Y'), n.strftime('%m'), n.strftime('%d'), ""]) + "/"
directory=str(instance.user.id) + "/"
name=str(uuid.uuid4()).replace("-", "")
extension=os.path.splitext(filename)[-1]
return ''.join([prefix, directory, ymd, name, extension])
class URC(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
group = models.ForeignKey(group, on_delete=models.CASCADE, null=True)
URN = models.ForeignKey(UPRM, on_delete=models.CASCADE)
UPRC = models.CharField(max_length=300)
image = models.ImageField(upload_to=get_upload_path)
def __str__(self):
return self.UPRC
#urls
if settings.DEBUG:
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
I will post any other necessary code.
Sorry for the poor English.
Postscript
The page is redirected without any error display.
But admin screen was able to upload.
class BaseModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
kwargs.setdefault('label_suffix', '')
super(BaseModelForm, self).__init__(*args, **kwargs)
#template
<form method="post" action="">
{% csrf_token %}
{{form.image.label_tag}}
{{form.image}}
{{form.UPRC.label_tag}}
{{form.UPRC}}
{{form.URN.label_tag}}
{{form.URN}}
<input class="btn btn-primary" type="submit" value="submit">
</form>
Your <form> tag misses the enctype, as explained here:
<form method="post" enctype="multipart/form-data">
You can take a look at this example.
https://www.pythonsetup.com/simple-file-uploads-django-generic-createview/
def form_valid(self, form):
self.object = Author(photo=self.get_form_kwargs().get('files')['photo'])
self.object = form.save()
return HttpResponseRedirect(self.get_success_url())
I'm writing a project where you can add photos to a website from a disk or other sites. In jquery I wrote a book marklet where I can add pictures from other site. But I have problem with uploading images from the disc. I wrote model, modelform, views and html file. When I choose a img file in the form all looks OK. I'm moved to image list web page, but there is not file what I whant to upload. Image file not saving. I don't know what I did wrong. Below is my code:
models.py
class Image(models.Model):
user = models.ForeignKey(settings.AUTH_USER_MODEL,
related_name='images_created')
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200,
blank=True)
url = models.URLField(blank=True)
image = models.ImageField(upload_to='images/%Y/%m/%d')
description = models.TextField(blank=True)
created = models.DateField(auto_now_add=True,
db_index=True)
users_like = models.ManyToManyField(settings.AUTH_USER_MODEL,
related_name='images_liked',
blank=True)
total_likes = models.PositiveIntegerField(db_index=True, default=0)
def __str__(self):
return self.title
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super(Image, self).save(*args, **kwargs)
def get_absolute_url(self):
return reverse('images:detail', args=[self.id, self.slug])
class Meta:
ordering = ["-image"]
forms.py
class ImageCreateForm(forms.ModelForm):
class Meta:
model = Image
fields = ('title', 'url', 'description')
widgets = {
'url': forms.HiddenInput,
}
def clean_url(self):
url = self.cleaned_data['url']
valid_extensions = ['jpg', 'jpeg']
extension = url.rsplit('.', 1)[1].lower()
if extension not in valid_extensions:
raise forms.ValidationError('Podany adres URL nie zawiera ' \
'obrazów w obsługiwanym formacie.')
return url
def save(self, force_insert=False,
force_update=False,
commit=True):
image = super(ImageCreateForm, self).save(commit=False)
image_url = self.cleaned_data['url']
image_name = '{}.{}'.format(slugify(image.title),
image_url.rsplit('.', 1)[1].lower())
# Pobranie pliku obrazu z podanego adresu URL.
response = request.urlopen(image_url)
image.image.save(image_name,
ContentFile(response.read()),
save=False)
if commit:
image.save()
return image
Upload from web page
class UploadImageForm(forms.ModelForm):
class Meta:
model = Image
fields = ('image', 'title', 'description')
def save(self, commit=True):
image = super(UploadImageForm, self).save(commit)
image_name = '{}.{}'.format(slugify(image.title),
image_url.rsplit('.', 1)[1].lower())
# Pobranie pliku obrazu z podanego adresu URL.
response = request.urlopen(image_title)
image.image.save(image_name,
ContentFile(response.read()),
save=False)
if commit:
image.save()
return image
Upload from dics
views.py
#login_required
def image_create(request):
if request.method == 'POST':
form = ImageCreateForm(data=request.POST)
if form.is_valid():
cd = form.cleaned_data
new_item = form.save(commit=False)
new_item.user = request.user
new_item.save()
create_action(request.user, 'Added Image', new_item)
messages.success(request, 'Obraz został dodany.')
return redirect(new_item.get_absolute_url())
else:
form = ImageCreateForm(data=request.GET)
return render(request,
'images/image/create.html',
{'section': 'images',
'form': form})
Upload from web page
#login_required
def image_upload(request):
if request.method == 'POST':
upload_form = UploadImageForm(request.POST, request.FILES)
if ulpoad_form.is_valid():
new_item=upload_form.save(commit=False)
new_item.image=request.FILES['image']
new_item.save()
messages.success(request, 'Obraz został dodany.')
return redirect('new_item.get_absolute_url()')
else:
upload_form=UploadImageForm()
return render(request, 'images/image/upload_image.html',
{'upload_form': upload_form, 'section': 'images' })
Upload from dics
And upload.html
{% block content %}
<h1>upload img</h1>
<form action="." method="post" enctype="multipart/form-data">
{{ upload_form.as_p }}
{% csrf_token %}
<input type="submit" value="Upload!!">
</form>
{% endblock %}
I would be grateful for help
I'm trying to upload an image. This is an avatar image for the profile of the user.
Currently, the form return no error, but I have nothing written on my database or in my folder media/avatar/.
What's wrong ?
My view :
def view_avatar(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES, instance=request.user.profile)
if form.is_valid():
form.save()
else:
form = UploadFileForm(instance=request.user.profile)
return render(request, 'avatar.html', locals())
My form :
class UploadFileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('avatar',)
My model :
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
birthdate = models.DateField(null=True, blank=True)
avatar = models.ImageField(upload_to='media/avatar/', blank=True, null=True)
It's because the form which you are using is inherited from forms.Form , you need to use forms.ModelForm for saving the instance directly.
Change this line,
class UploadFileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('avatar', )
def save(self, *args, **kwargs):
profile, created = Profile.objects.get_or_create(user=self.user)
profile.avatar = self.cleaned_data['avatar']
profile.save()
return profile
Also, edit in your views like this,
if form.is_valid():
file = form.save(commit=False)
file.user = request.user
file.save()
For making a profile you can use signals.
This way whenever a new user been added, a profile will be generated for that user automatically
Your models.py:
from django.conf import settings
from django.db.models.signals import post_save
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
birthdate = models.DateField(null=True, blank=True)
avatar = models.ImageField(upload_to='media/avatar/%y/%m/%d', blank=True, null=True)
def post_save_profile(sender, instance, created, *args, **kwargs):
if created:
try:
Profile.objects.create(user=instance)
except:
pass
post_save.connect(post_save_profile, sender=settings.AUTH_USER_MODEL)
and for updating the information like birthday and avatar you can use ModelForm.
forms.py:
class UploadFileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ('birthdate', 'avatar')
def __init__(self, *args, **kwargs):
super(UploadFileForm, self).__init__(*args, **kwargs)
self.fields['avatar'].required = False
your views.py:
def view_avatar(request):
user = request.user
if request.method == "POST":
form = UploadFileForm(request.POST, request.FILES, instance=user.profile)
if form.is_valid():
form.save()
for avatar in template you can use this:
<img src="{% if user.profile.avatar %}{{ user.profile.avatar.url }}{% else %}{% static 'no-avatar.jpg' %}{% endif %}"><i></i>
You can write custom Save method for this like this.
View:
def view_avatar(request):
if request.method == 'POST':
form = UploadFileForm(request.POST, request.FILES, user=request.user)
if form.is_valid():
form.save()
else:
form = UploadFileForm()
return render(request, 'avatar.html', locals())
Form:
class UploadFileForm(forms.Form):
class Meta:
model = Profile
fields = ('avatar', )
def __init__(self, *args, **kwargs):
self.user = kwargs.pop('user', None)
super(UploadFileForm, self).__init__(*args, **kwargs)
self.fields['avatar'].required = False
avatar = forms.FileField()
def save(self, *args, **kwargs):
user_profile, created = Profile.objects.get_or_create(user=self.user)
user_profile.avatar = self.cleaned_data.get('avatar')
user_profile.save()
return user_profile
I forgot the enctype !
The solution was :
<form method="POST" action="" enctype="multipart/form-data">