How to work with Mezzanine - python

processor_for.py
from django import forms
from django.http import HttpResponseRedirect
from mezzanine.pages.page_processors import processor_for
from .models import Book
class BookForm(forms.Form):
name = forms.CharField()
email = forms.EmailField()
#processor_for(Author)
def author_form(request, page):
form = BookForm()
if request.method == "POST":
form =BookForm(request.POST)
if form.is_valid():
# Form processing goes here.
redirect = request.path + "?submitted=true"
return HttpResponseRedirect(redirect)
return {"form": form}
models.py
from django.db import models
from time import time
class Book(models.Model):
book_name= models.CharField(max_length=200, unique = True)
def __unicode__(self):
return self.book_name
views.py
def create_book (request):
if request.POST:
form = BookForm(request.POST, request.FILES)
if form.is_valid():
form.save()
return HttpResponseRedirect('/all/')
else:
form = BookForm()
args= {}
args.update(csrf(request))
args['form'] = form
return render_to_response('create_Book.html', args)
urls.py
urlpatterns += patterns('',
url(r'^/xyz/$', create_book))
create_Book.html
<form action="/xyz/" method="post" enctype="multipart/form-data">{% csrf_token %}
{{form.as_ul}}
<input type="submit" name="submit" value="create"/>
</form>
This is what i am doing but still i am unable to access form. Where i am doing wrong. will be grateful to you. Please mark that what's wrong in code?

as per you code and your explanation in question .please see your code in urls.py
urlpatterns += patterns('',
url(r'^xyz/$', create_book)) # you should write like ^xyz/$
Please follow django doc

Two Syntax Problems:
1) Always define your processor name in " " like #processor_for("Author")
2) urls for page processors like :
url("^xyz/$", "mezzanine.pages.views.page", {"slug": "Author"}, name="Author"),

Related

Django form is valid() returns false

I am trying to do multiple file uploads in Django but am encountering some errors: form.is_valid() returning false. <br>
I have tried printing form.erorrs and it gives me the following:
<ul class="errorlist"><li>uploaded_images<ul class="errorlist"><li>“b'\xbd\x06D\xcd3\x91\x85,\xdf\xa5K\n'” is not a valid value.</li></ul></li></ul>
I am not sure how to interpret this general error. Been searching for quite some time but couldn't find an answer.
Edit:
Im also encountering a "This field is required." error
Perhaps this screenshot may help with debugging:
I must be missing something simple but I just can't find it!!
Another pair of eyes to help me sieve through would be very appreciated!
views.py
from django.shortcuts import render,redirect
from django.views.generic.edit import FormView
from .forms import BRForm
from .models import *
class BRHomeView(FormView):
form_class = BRForm
model = TargetImage
template_name = 'br/br-home.html'
context_object_name = 'bankrecon'
def get(self, request):
form = BRForm(request.POST, request.FILES)
return render(request, self.template_name, {'form': form, 'title': 'Bank Reconcilation'})
def post(self, request, *args, **kwargs):
form_class = self.get_form_class()
form = self.get_form(form_class)
files = request.FILES.getlist('uploaded_images')
print("POST")
print(request.POST)
print("FILES")
print(request.FILES)
print(form.errors)
if form.is_valid():
form.save()
return redirect('br-home')
models.py
from django.db import models
# Create your models here.
class UploadedImages(models.Model):
image_files = models.ImageField(null=True, blank=True, upload_to='images/')
class TargetImage(models.Model):
invoice_date = models.DateTimeField()
recon_date = models.DateTimeField()
uploaded_images = models.ManyToManyField(UploadedImages)
def __str__(self):
return self.invoice_date
forms.py
from django import forms
from django.core.validators import FileExtensionValidator
from .models import *
class BRForm(forms.ModelForm):
class Meta:
model = TargetImage
fields = ('invoice_date', 'recon_date', 'uploaded_images')
widgets = {
'invoice_date': forms.DateInput(attrs={'type': 'date'}),
'recon_date': forms.DateInput(attrs={'type': 'date'}),
'uploaded_images': forms.ClearableFileInput(attrs={'multiple': True, 'accept':'.jpeg, .png, .jpg'}),
}
relevant template code:
<div class="mt-5 d-flex justify-content-center">
<form action="" enctype="multipart/form-data" method="POST">
{% csrf_token %}
{{ form.as_p }}
<div class="d-flex justify-content-center">
<button class="btn btn-success mt-3" type="submit">Submit</button>
</div>
</form>
</div>
Extra info: My request.POST and request.FILES seems to be working fine:
POST
<QueryDict: {'csrfmiddlewaretoken': ['hiding this'], 'invoice_date': ['2021-02-01'], 'recon_date': ['2021-02-01']}>
FILES
<MultiValueDict: {'uploaded_images': [<InMemoryUploadedFile: first_slide (1).jpg (image/jpeg)>, <InMemoryUploadedFile: fourth_slide (1).jpg (image/jpeg)>]}>
Thank you all!!
Some errors that I see in your code:
You're trying to render a POST request in your get method.
You're not passing any data from POST request to your form instance. That's why is_valid() is returning False.
Change your code to something like this and see if it works:
...
def get(self, request):
form = BRForm()
return render(request, self.template_name, {'form': form, 'title': 'Bank Reconcilation'})
def post(self, request, *args, **kwargs):
form = BRForm(request.POST)
if form.is_valid():
form.save()
return redirect('br-home')
I have managed to solve this issue! <br>
Link: https://stackoverflow.com/a/60961015/10732211 <br>
I overhauled the entire thing and followed the above link. Probably the models relations have some issues that does not work. <br>
views.py
class BRHomeView(FormView):
# model = TargetImage
template_name = 'br/br-home.html'
context_object_name = 'bankrecon'
def get(self, request):
form = BRFormExtended()
return render(request, self.template_name, {'form': form, 'title': 'Bank Reconcilation'})
def post(self, request, *args, **kwargs):
form = BRFormExtended(request.POST,request.FILES)
files = request.FILES.getlist('image_files')
if form.is_valid():
print("Form Valid")
print(form.cleaned_data['invoice_date'])
print(form.cleaned_data['recon_date'])
user = request.user
invoice_date = form.cleaned_data['invoice_date']
recon_date = form.cleaned_data['recon_date']
target_image_obj = TargetImage.objects.create(user=user,invoice_date=invoice_date, recon_date=recon_date)
for file in files:
UploadedImage.objects.create(target_image=target_image_obj,image_files=file)
else:
print("Form Invalid")
return redirect('br-home')
forms.py
class BRForm(forms.ModelForm):
class Meta:
model = TargetImage
fields = ['invoice_date', 'recon_date']
widgets = {
'invoice_date': forms.DateInput(attrs={'type': 'date'}),
'recon_date': forms.DateInput(attrs={'type': 'date'}),
}
class BRFormExtended(BRForm):
image_files = forms.FileField(widget=forms.ClearableFileInput(attrs={'multiple': True}))
class Meta(BRForm.Meta):
fields = BRForm.Meta.fields + ['image_files',]
models.py
from django.contrib.auth.models import User
from django.utils import timezone
class TargetImage(models.Model):
user = models.OneToOneField(User,on_delete=models.CASCADE)
uploaded_date = models.DateTimeField(default=timezone.now)
invoice_date = models.DateTimeField()
recon_date = models.DateTimeField()
def __str__(self):
return self.user.__str__()
class UploadedImage(models.Model):
target_image = models.ForeignKey(TargetImage, on_delete=models.CASCADE)
image_files = models.ImageField(null=True, blank=True, upload_to='images/')
Also, it would be helpful to have a media root folder and edits to urls.py is also required.
urls.py
from django.urls import path
from .views import BRHomeView
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
path('', BRHomeView.as_view(), name='br-home'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
settings.py
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
STATIC_URL = '/static/'
STATICFILES_DIRS = (os.path.join(BASE_DIR, "static"),)
Hopefully this will help someone!

Why is my Django form is not displaying anything?

I am following a tutorial in which we will create a form to hold simple object parameters.
Here's the code:
forms.py
from django.forms import ModelForm
from .models import Item
class ItemForm(ModelForm):
class Meta:
model = Item
fields = ['item_name', 'item_desc', 'item_price', 'item_image']
models.py
from django.db import models
class Item(models.Model):
def __str__(self):
return self.item_name
item_name = models.CharField(max_length = 200)
item_desc = models.CharField(max_length= 200)
item_price = models.IntegerField()
item_image = models.CharField(max_length=500, default ="https://i.jamesvillas.co.uk/images/jvh/holiday-destinations/resort/food-placeholder.jpg" )
urls.py
from . import views
from django.urls import path
urlpatterns = [
path('', views.index, name = 'index'),
path('item/', views.item, name = 'item'),
path('info/', views.info, name = "info"),
path('<int:item_id>/', views.detail, name = "detail" ),
#add form
path('add', views.create_item, name = "create"),
]
views.py
from django.shortcuts import render, redirect
from django.http import HttpResponse
from .models import Item
from django.template import loader
from .forms import ItemForm
#Some code here
def create_item(request):
form = ItemForm(request.POST or None)
if (form.is_valid()):
form.save()
return redirect('food/index')
return render(request, 'food/item-form.html', {'form': form})
food/item-form.html
<form method = "POST">
{% csrf_token %}
{{ form }}
<button type= "Submit" >Save</button>
</form>
Now when I go to http://localhost:8000/food/add, it displays an empty page! I have followed the tutorial the exact same way then why is My project not working?
correct your views.py
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import NameForm
def get_name(request):
# if this is a POST request we need to process the form data
if request.method == 'POST':
# create a form instance and populate it with data from the request:
form = NameForm(request.POST)
# check whether it's valid:
if form.is_valid():
# process the data in form.cleaned_data as required
# ...
# redirect to a new URL:
return HttpResponseRedirect('/thanks/')
# if a GET (or any other method) we'll create a blank form
else:
form = NameForm()
return render(request, 'name.html', {'form': form})

django context processor form not showing errors when submitting

I`m using context processor to render form to the base template in my project and the form seems to work ok, except it doesnt show any errors for required fields being blank and etc. The page is simply reloaded even if fields are not filled in.
I used this approach in other project before, and it worked just fine, but now I cant really figure out what happened and why it is like so.
Here is my forms.py:
from django import forms
class VersionSelectorForm(forms.Form):
mode = forms.ChoiceField(widget=forms.RadioSelect(),
choices=(('live', 'Live'), ('history', 'History')),
initial='live',
required=True,
help_text='Required')
date = forms.DateField(widget=forms.TextInput(attrs={'class': 'datepicker'}),
required=True,
help_text='required')
def clean(self):
cleaned_data = super(VersionSelectorForm, self).clean()
mode = cleaned_data.get('mode')
date = cleaned_data.get('date')
if mode == 'history' and not date:
msg = 'Date should be picked if \'History\' mode selected'
self.add_error('date', msg)
view.py:
from django.shortcuts import redirect
from .forms import VersionSelectorForm
def select_version(request):
if request.method == "POST":
form = VersionSelectorForm(request.POST)
if form.is_valid():
print('I am valid')
mode = form.cleaned_data["mode"]
date = form.cleaned_data["date"]
if mode == "History":
request.session['selected_date'] = date
else:
request.session['selected_date'] = None
else:
form = VersionSelectorForm()
return redirect(request.META['HTTP_REFERER'])
context_processors.py:
from .forms import VersionSelectorForm
def VersionSelectorFormGlobal(request):
return {'version_selector_form': VersionSelectorForm()}
urls.py:
from django.contrib import admin
from diagspecgen import views
urlpatterns = [
url(r'^admin/', include(admin.site.urls)),
url(r'^select_version/$', views.select_version, name='select_version'),
]
snippet from base.html:
<section><div>
<form method="post" action="{% url 'select_version'%}">
{% csrf_token %}
{{ version_selector_form.as_p }}
<button type="submit">Submit</button>
</form>
</div></section>
and of course I have added 'diagspecgen.context_processors.VersionSelectorFormGlobal' to context_processors list in settings.py.
Looking forward for any help and thanks in advance for that.
You should not use context processor to render your form, but instead pass it to the django shortcut render function.
You could do something like this:
def select_version(request):
if request.method == "POST":
form = VersionSelectorForm(request.POST)
if form.is_valid():
print('I am valid')
mode = form.cleaned_data["mode"]
date = form.cleaned_data["date"]
if mode == "History":
request.session['selected_date'] = date
else:
request.session['selected_date'] = None
else:
form = VersionSelectorForm()
return render(request, 'template.html', {'form': form})
Don't forget the import from django.shortcuts import render
Link to the doc: https://docs.djangoproject.com/en/2.0/topics/forms/#the-view

How to make delete button in Django

Help me please to understand how to make the delete button, its must to delete a Cat
class Cat(models.Model):
class Meta():
db_table = "cat"
paw = models.IntegerField(default=4)
name = models.CharField(max_length=30, null=False, default='Cat')
age = models.IntegerField(default=False, null=False)
species = models.CharField(max_length=50, blank=True)
hairiness = models.IntegerField(default=False, null=False)
def __str__(self):
return self.name
This is my views.py, hope you can help. (it's need for my job interview on Monday)
from django.shortcuts import render, get_object_or_404
from .models import Cat
from .forms import CatForm
from django.shortcuts import redirect
def home(request):
template = "base.html"
queryset = Cat.objects.all()
context = {
"object_list": queryset
}
return render(request, template, context)
def new_cat(request):
if request.method == "POST":
form = CatForm(request.POST)
if form.is_valid():
cat = form.save(commit=False)
cat.save()
return redirect('/', pk=cat.pk)
else:
form = CatForm()
return render(request, 'new_cat.html', {'form': form})
def cat_edit(request, pk):
cat = get_object_or_404(Cat, pk=pk)
if request.method == "POST":
form = CatForm(request.POST, instance=cat)
if form.is_valid():
cat = form.save(commit=False)
cat.save()
return redirect('/', pk=cat.pk)
else:
form = CatForm(instance=cat)
return render(request, 'new_cat.html', {'form': form})
site is asc to addd more details, but i just don't know what else, i can add.
from django.conf.urls import url
from . import views
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^new/$', views.new_cat, name='new_cat'),
url(r'^edit/(?P<pk>[0-9]+)/$', views.cat_edit, name='cat_edit'),
]
At first, you should create a cat_delete view, which should look something like this:
def cat_delete(request, pk):
cat = get_object_or_404(Cat, pk=pk) # Get your current cat
if request.method == 'POST': # If method is POST,
cat.delete() # delete the cat.
return redirect('/') # Finally, redirect to the homepage.
return render(request, 'template_name.html', {'cat': cat})
# If method is not POST, render the default template.
# *Note*: Replace 'template_name.html' with your corresponding template name.
Then, you should map this view in your urls.py:
from django.conf.urls import url
from . import views
app_name = 'cats'
# Note that app_name is added here!
# It is used as a namespace in order to reverse your urls better.
# See usage in template.
urlpatterns = [
# ...
url(r'^delete/(?P<pk>[0-9]+)/$', views.cat_delete, name='cat_delete')
]
In your template, you should create a form with delete button, which will simply send a POST request to the delete view:
<form action="{% url 'cats:cat_delete' cat.id %}" method="post">
{% csrf_token %}
<input type="submit" value="Delete cat">
</form>
Look closely on the form's action:
{% url 'cats:cat_delete' cat.id %}
Here I am using the app_name from urls.py that I previously added in order to resolve your urls by name, not by path. Now cats:cat_delete will evaluate to cats/delete/<pk>. And of course you pass the cat.id.
This should do the trick with deleting instance of your Cat model. Hope I helped.

How do I save data of the user?

I have Model:
models.py
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name='userprofile')
points = models.IntegerField(default=0)
urls.py
urlpatterns = [
url(r'^$', demo),
url(r'^demo/$', demo),
]
demo.html
<form action="" method="POST">
<button type="submit">+</button>
</form>
views.py
def demo(request):
if request.method == "POST":
# I don't understand how I can get "points" from the model "UserProfile"
#to add 1 and to save in the DB
return render(request, 'app/demo.html')
I would like that after pressing on the button points of the user increased one. I really cannot figure it out.
Try something like this
def demo(request):
if request.method == "POST":
profile = UserProfile.objects.get(user=request.user)
profile.points += 1
profile.save()
return render(request, 'app/demo.html', {"user":request.user,
"profile":profile)

Categories