objects.all() not working - django - python

i have below model,
from django.db import models
# Create your models here.
class user_files(models.Model):
Filename = models.CharField(max_length=50)
Browse = models.FileField()
and in my view i want all data from above model,
my view is..
def user_in(request):
if not request.user.is_authenticated:
return render(request, 'accounts/logout.html')
else:
if request.method == 'POST':
form_new = Fileupload(request.POST, request.FILES )
#instance=form_new.save(commit=False)
#instance.save()
if form_new.is_valid():
form_new.save()
return redirect('in')
else:
form_new = Fileupload()
data = user_files.objects.all()
return render(request, 'accounts/in.html', {'form_new': form_new}, {'data':data})
and in my template i am writing,
<div>
{% if request.user.is_authenticated %}
{% for da in data %}
<h3>{{data.Filename}}</h3>
{% endfor %}
{% endif %}
</div>
but in my view, it is showing error for objects.all() as unresolved attribute.
i am stuck . i am using pycharm.
How to solve this?
Thanks in advance

You are rendering like this
<h3>{{data.Filename}}</h3>
'data' is a QuerySet it will not have any Filename attribute.
you have to do this.
<h3>{{da.Filename}}</h3>

Related

How do I get the ID of an image

I'm a Django beginner, how do I get the ID of each image uploaded with form?
class Image(models.Model):
imageuploader_profile=models.ForeignKey(settings.AUTH_USER_MODEL)
upload_image=models.ImageField()
def upload(request):
if request.method == 'POST':
form=UploadForm(request.POST, request.FILES)
if form.is_valid():
post=form.save(commit=False)
post.imageuploader_profile=request.user
post.save()
return redirect....
else:
form=UploadForm
return render......
view.py
def home(request) :
all_images=Image objects.filter(imageuploader_profile=request.user)
context={'all_images':all_images}
return render(request, 'home.html', context)
My home.html
{% for post in all_images %}
{% if post upload_images %}
<img src="{{ post upload_image.url }}">
{% endif %}
{% endfor%}
I want to get all IDs in my template.
You can write a new method/view to get all IDs:
def get_images_ids():
images_ids = Image.objects.values_list('id)
print(images_ids)
return images_ids
Here the explanation for values_list (you also can use values() if you need more, or the attribute flat=True).
If you call get_images_ids() you get all IDs of all images in a queryset (or in a list with flat=True). If you need to filter them use .filter().
In your views.py
def home(request) :
all_images=Image objects.filter(imageuploader_profile=request.user)
context={'all_images':all_images, all_images_ids: get_images_ids()}
return render(request, 'home.html', context)
In your template do this:
{% for post in all_images %}
{% if post upload_images %}
<img src="{{ post.upload_image.url }}">
<span>{{ post.id }}</span>
{% endif %}
{% endfor%}
or
<ul>
{% for id in all_images_ids %}
<li>{{ id }}</li>
{% endfor%}
</ul>
You can't get id of the image unless you first create an object in database, in other words you will have to execute post.save() first and then you can run post.id to get id. Here is an example with your code.
class Image(models.Model):
imageuploader_profile=models.ForeignKey(settings.AUTH_USER_MODEL)
upload_image=models.ImageField()
def upload(request):
if request.method == 'POST':
form=UploadForm(request.POST, request.FILES)
if form.is_valid():
post=form.save(commit=False)
post.imageuploader_profile=request.user
post.save()
print(post.id) # This will print id of submitted post in your console
return redirect....
else:
form=UploadForm
Note: ID of post is automatically created in the database after you run post.save()
You can get the ID of the image after post.save() executes.
So before the return statement you can access post.id or post.pk to get the image ID.
UPDATE:
class Image(models.Model):
imageuploader_profile=models.ForeignKey(settings.AUTH_USER_MODEL)
upload_image=models.ImageField()
def upload(request):
if request.method == 'POST':
form=UploadForm(request.POST, request.FILES)
if form.is_valid():
post=form.save(commit=False)
post.imageuploader_profile=request.user
post.save()
# here you can access post.id or post.pk
return redirect....
else:
form=UploadForm
If you want to get all uploaded images id then use Image.objects.values_list('id)

Django form is not valid but no error is sent

I started to learn Django today, but I am stuck at using forms. I have created two forms: /contact and /blog-new. The form at the Contact page is working fine, but the one at /blog-new is redirecting me to the home page after the submission button is pressed and no information is printed in the terminal nor saved in the database.
Code on Github
I appreciate if someone can explain to me what I did wrong as I cannot figure it out. Thank you!
mysite/blog/forms.py
from django import forms
from .models import BlogPost
class BlogPostModelForm(forms.ModelForm):
class Meta:
model = BlogPost
fields = ['title', 'slug', 'content']
mysite/blog/views.py
from .forms import BlogPostModelForm
def blog_post_create_view(request):
# create objects
# ? use a form
# request.user -> return something
form = BlogPostModelForm(request.POST or None)
if form.is_valid():
print(form.cleaned_data)
form.save()
form = BlogPostModelForm()
template_name = 'form.html'
context = {'form': form}
return render(request, template_name, context)
mysite/blog/models.py
from django.db import models
# Create your models here.
class BlogPost(models.Model):
title = models.TextField()
slug = models.SlugField(unique=True)
content = models.TextField(null=True, blank=True)
mysite/mysite/urls.py
from blog.views import (
blog_post_create_view,
)
urlpatterns = [
..
path('blog-new', blog_post_create_view),
..
]
mysite/templates/form.html
{% extends "base.html" %}
{% block content %}
{% if title %}
<h1>{{ title }}</h1>
{% endif %}
<form method='POST' action='.'> {% csrf_token %}
{{ form.as_p }}
<button type='submit'>Send</button>
</form>
{% endblock %}
You need to point to right url in action attribute of form.
<form action="/blog-new/" method="post">
{% csrf_token %}
{{ form }}
<input type="submit" value="Submit">
</form>
I think it's not necessary in your case but you could also refactor your view to match the docs.
from django.http import HttpResponseRedirect
from django.shortcuts import render
from .forms import SomeForm
def some_view(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 = SomeForm(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 = SomeForm()
return render(request, 'template_name.html', {'form': form})
You need to point to right url in action attribute of form.
That was not actually the solution but something that helped me to figure out what was wrong.
It is not necessary to point to /blog-new/ as . for action will point to the same page, but I have tried with /blog-new/ as action URL and I was surprised to see that /blog-new/ page doesn't exist.
The bug was in mysite/mysite/urls.py for missing a /:
path('blog-new', blog_post_create_view),
It is funny (and annoying) how a symbol like / missing from your code will mess up everything and make you spend hours trying to find a solution as simple as that.
Thank you for your time spend to have a look over my code and try to help me!

I am not able to save the form data to databse in django

I want to add data through form and see it queried in my template
blog url:
urlpatterns = [
url(r'^admin/',admin.site.urls),
url(r'^blog/',include('content.urls',)),
]
content url:
urlpatterns = [
url(r'^add/$', views.add_content, name='content'),
]
models.py
from django.db import models
class AddContent(models.Model):
content_name = models.CharField(max_length=100, default='', blank=False, unique=True)
def __str__(self):
return self.content_name
forms.py
from django import forms
from .models import AddContent
class AddContentForm(forms.ModelForm):
class Meta:
model = AddContentModel
fields = [
"content_name",
]
views.py
def add_content(request):
form = AddContentForm(request.POST or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
return redirect("/blog/content/")
content_data = AddContent.objects.all()
context = {
"form":form,
"content":content_data,
}
return render(request, "add_content.html", context)
def view_content(request):
view_data = AddContent.objects.all()
context = {
"show_content":view_data,
}
return render(request, 'show_content.html', context)
templates:
add_content.html
{% extends 'base.html' %}
{% block content %}
<form method='POST' action="/blog/content/">
{% csrf_token %}
{{ form.as_p }}
<input type='submit' value='Add Content'/>
<h3>Recent content</h3>
{% for show in show_content %}
<p>{{ show.content_name }}</p>
{% endfor %}
{% endblock %}
The form data is not being saved, when I add it through admin interface it gives the result but form fails.
(this is just some useless content that I am writing in the bracket, stackoverflow didn't allow me posting as it looks like my post is mostly code; please add more details it said but i think the code has lot of details and i cant write anything just for the sake of length)
Your model form should look like this
from django import forms
from .models import AddContent
class AddContentForm(forms.ModelForm):
class Meta:
model = AddContent
fields = [
"content_name",
]
You've defined the wrong model name in the Meta class of model form. It should be AddContent not AddContentModel
I'm new to django too, but don't you need to specify the request inside the functions in views.py like :
def add_content(request):
if(request.method == 'POST'):
# rest of code here
Your form does not post to the view that saves the data; it posts directly to the view_content view, which ignores the data completely.
You can set the form action to "." to get it to post back to the same view that rendered it.
(As an additional point, you should avoid hard-coding URLs. Use the {% url %} tag in templates, and the reverse() function in views, to output URLs based on view names.)
First :
Correct the redirect() in your form.
return redirect("add_content", request.POST= None)
Second : you need to specify a URL for the content view : view_content
url(r'^content/$', views.view_content, name='content'),
And You need a template to render content (show_content.html :
{% extends 'base.html' %}
{% block content %}
<h3>Recent content</h3>
{% for show in show_content %}
<p>{{ show.content_name }}</p>
{% endfor %}
{% endblock %}
Edit :
Your form is not well defined. I edit my answer to make it complete :
You have to correct the model in your form (AddContent not AddContentModel) :
class Meta:
model = **AddContent**
fields = [
"content_name",
]

How correctly save multiple files in django?

I need form where user can create article with several images. I use django-multiupload app for image field. I can select several images but when I try to submit the form I have message under the image field: "Field is empty and field is required". Where is my mistake? Why I have such message when image field is not empty?
Also maybe someone can advice good examples or apps to save several images. I would be very grateful for any help.
models.py:
class Article(models.Model):
description = models.TextField(_('Description'))
class Image(models.Model):
article= models.ForeignKey(Article, on_delete=models.CASCADE)
image = models.FileField(_('Image'), upload_to='images/%Y/%m/%d/')
forms.py:
class ArticleForm(forms.ModelForm):
class Meta:
model = Article
fields = ('description', )
image = MultiFileField()
def save(self, commit=True):
instance = super(ArticleForm, self).save(commit)
for each in self.cleaned_data['image']:
Image.objects.create(image=each, article=instance)
return instance
views.py:
def article_add(request):
data = dict()
if request.method == 'POST':
article_form = ArticleForm(request.POST, request.FILES)
if article_form.is_valid():
article = article_form.save(commit=False)
******
article.save()
data['form_is_valid'] = True
articles = Article.objects.all
context = {'articles': articles}
context.update(csrf(request))
data['html_article'] = render_to_string('project/article_list.html', context)
else:
data['form_is_valid'] = False
else:
article_form = ArticleForm()
context = {'article_form': article_form}
data['html_article_form'] = render_to_string('project/article_add.html', context, request=request)
return JsonResponse(data)
article_add.html:
{% load widget_tweaks %}
<form method="post" action="{% url 'article_add' %}" class="article-add-form">
{% csrf_token %}
{% for field in article_form %}
<div class="form-group{% if field.errors %} has-danger{% endif %}">
<label class="form-control-label" for="{{ field.id_for_label }}">{{ field.label }}</label>
{% render_field field class="form-control" %}
{% for error in field.errors %}
<div class="form-control-feedback">{{ error }}</div>
{% endfor %}
</div>
{% endfor %}
<button type="submit">Submit</button>
</form>
Try adding "min_num" constraint on the image field,
image = MultiMediaField(min_num=1, media_type='image')
EDIT
def article_add(request):
if request.method == 'POST':
article_form = ArticleForm(request.POST, request.FILES)
if article_form.is_valid():
article = article_form.save(commit=False)
******
article.save()
#assume you have already a view in the name 'article_list'.
return redirect('article_list')
else:
article_form = ArticleForm()
context = dict(article_form=article_form)
return render(request, 'project/article_add.html', context)
The problem maybe because you were trying to render two templates in a single view, also when using django template rendering render is a shortcut function, which is mostly preferred to use, rather than string converting and parsing into json.
Also, 'article_list' must be another view, which shows the list of all the articles, after adding a new article, you should consider redirecting to the list view. Here you were trying to render multiple templates, in a single view. You could make of something like this in your list view,
def article_list(request):
articles = Article.objects.all()
context = dict(articles=articles)
return render(request, 'project/article_list.html', context)
Although, these are my personal opinion regarding the code you just shared. Try this approach...

View is not refreshing after post

I use a simple form to edit the name of a invoice (invoice_text). When I submit the changes it redirects back to index page. The problem is that the index page is showing the old records. This is only in Firefox. Internet Explorer shows the changes directly. F5 helps, but of course it needs to show the new (edited) information.
forms.py
class InvoiceForm(ModelForm):
class Meta:
model = Invoice
fields = ('Invoice_text',)
views.py
def index(request):
latest_invoice_list = Invoice.objects.order_by('-pub_date')[:5]
context = {'latest_invoice_list': latest_invoice_list}
return render(request, 'invoices/index.html', context)
def invoice_edit(request, pk):
obj = get_object_or_404(Invoice, pk=pk)
if request.method == "POST":
form = InvoiceForm(request.POST, instance=obj)
if form.is_valid():
obj = form.save(commit=False)
obj.Invoice_text = request.POST['Invoice_text']
obj.save()
return HttpResponseRedirect('/invoices/')
else:
form = InvoiceForm(instance=obj)
return render(request, 'polls/edit_Invoice.html', {'form': form})
Index.html template
{% if latest_invoice_list %}
<ul>
{% for invoice in latest_invoice_list %}
<li>{{ invoice.invoice_text }} | edit</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
This is strange, but you should be able to use the #never_cache decorator to prevent it:
from django.views.decorators.cache import never_cache
#never_cache
def index(request):
....

Categories

Resources