How to save url of the image in database with Django - django

i am new in Django, how to save url of the image in db using django. Thank you very much, sorry my english, i am learning too.
views.py
from django.shortcuts import render
from django.views.decorators.http import require_POST
from .models import Cad_component
from django import forms
from django.views.decorators.http import require_http_methods
class register_data(forms.ModelForm):
class Meta:
model = Cad_component
fields = ('title','slug','description','start_date','imagviewe')
def home(request):
imagesData = Cad_component.objects.all()
template_name = 'index.html'
context = {
'imagesData': imagesData
}
return render(request, template_name, context)
def register(request):
if request.method == "POST":
form = register_data(request.POST)
print (form)
if form.is_valid():
datas = form.save(commit=True)
#datas.image.save(request.read['title'],request.read['image'])
datas.save()
else:
form = register_data()
return render(request, 'register.html', {'form': form})
models.py
from django.db import models
import datetime
class ComponentManager(models.Manager):
def search(self, query):
return self.get_queryset().filter(
models.Q(name__icontains=query) | \
models.Q(description__icontains=query)
)
class Cad_component(models.Model):
title = models.CharField('Title', max_length=100)
slug = models.SlugField('Link')
description = models.TextField('Description', blank=True)
start_date = models.DateField('Data: ', null=True, blank=True)
image = models.ImageField(upload_to='img', verbose_name='Imagem', null=True, blank=True)
created_at = models.DateTimeField('Criado em ', auto_now_add=True)
updated_at = models.DateTimeField('Atualizado em', auto_now=True)
objects = ComponentManager()
def __str__(self):
return self.title

I was able to solve this problem, with a configuration that Django does in the HTML file. Just add: enctype = "multipart / form-data" in the FORM tag.
Follow:
<form class="needs-validation" method="post" enctype="multipart/form-data">
Any doubts I am available.

from django.core.files.storage import FileSystemStorage
//inside the view function
myfile = request.FILES['files']
f = FileSystemStorage()
filename = f.save(myfile.name, myfile)
url = f.url(filename)
Now you can store this url.
Give an up if it worked... I am new to stackoverflow.

Related

Django form not saving even after everything seems all right

My view:
'''
from django.shortcuts import render
from django.http import HttpResponse
from .models import Post
from .forms import createPostForm
def showPosts(request):
if request.method == "POST":
crf = createPostForm(request.POST)
crf.author = request.user
crf.save()
else:
crf = createPostForm()
context = {
'post' : Post.objects.all(),
'crf' : crf
}
return render(request, 'Content/FeedsPage.html', context)
'''
My Model:
'''
from django.db import models
from django.contrib.auth.models import User
class Post(models.Model):
# image = models.ImageField(blank=True, null=True, upload_to='post_images/')
# video = models.FileField(blank=True, null=True, upload_to='post_videos/')
title = models.CharField(max_length=100)
description = models.CharField(blank=True, max_length=1000)
date_posted = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
'''
My Template:
'''
<form enctype="multipart/form-data" novalidate method="post">
{%csrf_token%}
<div class="fieldWrapper">
{{crf.title.errors}}
{{crf.title}}
</div>
<div class="fieldWrapper">
{{crf.description.errors}}
{{crf.description}}
</div>
<button class="primaryButton" type="submit">submit</button>
</form>
'''
My Form:
'''
from django import forms
from .models import Post
class createPostForm(forms.ModelForm):
title = forms.CharField(
widget = forms.TextInput(attrs={
'placeholder': 'Give a sweet title',
'autocomplete' :'off'
})
)
description = forms.CharField(widget=forms.TextInput(attrs={
'placeholder': 'Please elaborate a little',
'autocomplete' :'off'
}))
class Meta:
model = Post
fields = '__all__'
'''
I removed the is_valid() function to see whats happening and apperently its showing
'The Post could not be created because the data didn't validate'
Please somebody help
This save() method accepts an optional commit keyword argument, which accepts either True or False. If you call save() with commit=False, then it will return an object that hasn't yet been saved to the database. Which is neat for some post processing before actually saving it! So, you method should look something like this.
def showPosts(request):
if request.method == "POST":
crf = createPostForm(request.POST)
if crf.is_valid():
form = crf.save(commit=False)
form.author = request.user
form.save()
else:
crf = createPostForm()
context = {
'post' : Post.objects.all(),
'crf' : crf
}
return render(request, 'Content/FeedsPage.html', context)

Model ImageField and save in a specific path

This is my model:
def group_based_upload_to(instance, filename):
return "media/image/lavorazione/{}".format(instance.prestazione.id,)
class ImmaginiLavorazioni(models.Model):
immagine = models.ImageField(upload_to=group_based_upload_to)
prestazione = models.ForeignKey(Listino, on_delete=models.SET_NULL, null=True,
blank=True, default=None, related_name='Listino3')
and my form:
class ImmagineUploadForm(forms.ModelForm):
class Meta:
model = ImmaginiLavorazioni
exclude = ('preventivo', )
I need a view to save an image in a specific path.
The name of path must be the pk of foreign key.
How can I do that?
I use a model of how a blog post works. You can adjust the example on your needs. You should try and avoid saving the location path from a view.
On your models.py:
# Create your models here.
def upload_location(instance, filename):
filebase, extension = filename.split(".")
return "%s/%s" % (instance.id, filename)
class Post(models.Model):
title = models.CharField(max_length=120)
slug = models.SlugField(unique=True)
image = models.ImageField(upload_to=upload_location,
null=True,
blank=True,
height_field="height_field",
width_field="width_field")
height_field = models.IntegerField(default=0)
width_field = models.IntegerField(default=0)
content = HTMLField()
formfield_overrides = {
models.TextField: {'widget': AdminPagedownWidget },
}
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
On your forms.py:
from django import forms
from pagedown.widgets import PagedownWidget
from pagedown.widgets import AdminPagedownWidget
from .models import Post
class PostForm(forms.ModelForm):
content = forms.CharField(widget=PagedownWidget(show_preview=False))
class Meta:
model = Post
fields = [
"title",
"content",
"image"
]
class PostModelForm(forms.ModelForm):
content = forms.CharField(widget=AdminPagedownWidget())
class Meta:
model = Post
fields = '__all__'
And on your settings.py:
MEDIA_URL = "/media/"
MEDIA_ROOT = os.path.join(os.path.dirname(BASE_DIR), "media_cdn")
Here is your view.py:
# Create your views here.
def post_create(request):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
form = PostForm(request.POST or None, request.FILES or None)
if form.is_valid():
instance = form.save(commit=False)
instance.save()
messages.success(request, "Succefully Created")
return HttpResponseRedirect(instance.get_absolute_url())
context = {
"form": form,
}
return render(request, "post_form.html", context)
The next code has an example without form but you can modify based on your needs.
Below the settings.py
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.realpath(__file__))
MEDIA_ROOT = os.path.join(BASE_DIR, '../media')
Firstable, I defined the path of the image in the helpers.py
from django.conf import settings
from datetime import datetime
def upload_to_image_post(self, filename):
"""
Stores the image in a specific path regards to date
and changes the name of the image with for the name of the post
"""
current_date = datetime.now()
return '%s/posts/main/{year}/{month}/{day}/%s'.format(
year=current_date.strftime('%Y'), month=current_date.strftime('%m'),
day=current_date.strftime('%d')) % (settings.MEDIA_ROOT, filename)
You could define the image's name with some code like this one. But you have to regard you should have the pk to replace the name of the image
ext = filename.split('.')[-1]
name = self.pk
filename = '%s.%s' % (name, ext)
So, I called the def in my models.py, specifically in the image's field
from django.db import models
from django.utils.text import slugify
from .helpers import upload_to_image_post
class Post(models.Model):
"""
Store a simple Post entry.
"""
title = models.CharField('Title', max_length=200, help_text='Title of the post')
body = models.TextField('Body', help_text='Enter the description of the post')
slug = models.SlugField('Slug', max_length=200, db_index=True, unique=True, help_text='Title in format of URL')
image_post = models.ImageField('Image', max_length=80, blank=True, upload_to=upload_to_image_post, help_text='Main image of the post')
class Meta:
verbose_name = 'Post'
verbose_name_plural = 'Posts'
I hope this helped you
Now this is my models:
def group_based_upload_to(instance, immagine):
return "media/preventivo/{pk}/{image}".format(pk=instance.preventivo.id, image=immagine)
class ImmaginiLavorazioni(models.Model):
immagine = models.ImageField(upload_to=group_based_upload_to)
preventivo = models.ForeignKey(Preventivo, on_delete=models.SET_NULL, null=True, blank=True,
default=None, related_name='Listino3')
And this is my view:
def upload_immagine(request, pk):
member = get_object_or_404(Preventivo, pk=pk)
if request.method == 'POST':
form = ImmagineUploadForm(request.POST or None, request.FILES or None)
if form.is_valid():
newimmagine = form.save(commit=False)
newimmagine.preventivo_id = member.pk
newimmagine.save()
return redirect('preventivo_new2', pk=member.pk)
else:
form = ImmagineUploadForm(request.POST or None, request.FILES or None)
return render(request, 'FBIsystem/upload_immagine.html', {'member': member, 'form': form})
It save in db the file path and the foreign key like:
immagine= media/preventivo/6/image.jpg
preventivo_id = 6
but not create a folder and not save the uploaded image...

how to render django forms manually?

am new in Django. Does anybody know how to implement manual?
I have newsletter app:
newsletter/views.py
from django.shortcuts import render
from .forms import NewsUserForm
from . models import NewsUsers
# Create your views here.
def newsletter_subscribe(request):
if request.method == 'POST':
form = NewsUserForm(request.POST)
if form.is_valid():
cd = form.cleaned_data
instance = form.save(commit=False)
if NewsUsers.objects.filter(email=instance.email).exists():
print('your email Already exists in our database')
else:
instance.save()
print('your email has been submitted to our database')
else:
form = NewsUserForm()
context = {'form':form}
template = "home/base.html"
return render(request, template, context)
newsletter/models.py
from django.db import models
# Subscribe models.
class NewsUsers(models.Model):
name = models.CharField(max_length = 30)
last_name = models.CharField(max_length = 30)
email = models.EmailField()
date_added = models.DateField(auto_now_add=True)
class Meta:
verbose_name = "NewsUser"
verbose_name_plural = "NewsUsers"
def __str__(self):
return self.email
newslettter/urls.py
from django.urls import path
from .views import newsletter_subscribe
app_name = 'newsletter'
urlpatterns = [
path('subscribe', newsletter_subscribe, name='subscribe'),
]
How to render this django forms manually, from third app to home template?
And i have in home app base template with following code:
home/templates/base.html
How to use this form on this template?

Django 2.0.3 adding data to the database

I have a small problem with adding data to the database in django 2.0.3
I created the following model:
from django.contrib.auth.models import User
class UserInputSignal(models.Model):
name = models.CharField(max_length=512)
author = models.ForeignKey(User, on_delete=models.CASCADE)
input_file = models.FileField(upload_to='signals/', null=True)
I tried to solve the problem using this form:
from django import forms
from .models import UserInputSignal
class UserInputSignalForm(forms.ModelForm):
name = forms.CharField()
input_file = forms.FileField()
class Meta:
model = UserInputSignal
fields = ('name', 'input_file', )
and this view:
from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.contrib.auth import authenticate
from .forms import UserInputSignalForm
#login_required
def storage(request):
form = UserInputSignalForm(request.POST or None)
if request.method == 'POST':
if form.is_valid():
name = request.POST.get('name')
author = request.POST.get(request.user)
input_file = request.POST.get('input_file')
return redirect('home')
else:
form = UserInputSignalForm()
return render(request, 'storage.html', {'form': form})
In the template I called, I created the form as follows:
<form method="POST" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
I am able to load a page with a form, but it does not post data to the database. I would like to add that I am a novice in django and some mechanisms are just plain understandable for me. Can I ask someone for help with this problem?
Before the redirect, call form.save()
Okay, i worked on your code and it works with me with slight modifications:
models.py
class UserInputSignal(models.Model):
name = models.CharField(max_length=512)
author = models.ForeignKey(User, on_delete=models.CASCADE)
input_file = models.FileField(upload_to='signals/', null=True)
objects = models.Manager()
#this returns the name for your modelobject
def __str__(self):
return self.name
forms.py
#excluded the assiging as fields defination is enough in itself
class UserInputSignalForm(forms.ModelForm):
class Meta:
model = UserInputSignal
#this will exclude the formfield it self but the author will be saved as the person who is logged in
exclude = ["author"]
Edited - Views.py
#login_required
def storage(request):
#authentication for author field using request.user
insta = UserInputSignal(author=request.user)
print(request.user)
form = UserInputSignalForm(request.POST or None, request.FILES or None,instance=insta)
if request.method == 'POST':
if form.is_valid():
signal = form.save(commit=False)
signal.save()
return redirect('home')
else:
form = UserInputSignalForm(instance=insta)
return render(request, 'storage.html', {'form': form})
JlucasRs was right to tell you to use form.save(), but you needed to assign form to something and need not use model fields here as forms.py does that for you.
app/Urls.py - Just for reference
urlpatterns = [
path('home/', home, name='home'),
path('storage/', storage, name='storage'),
]
Edit- Admin.py
from .models import PostModel, UserInputSignal
class UserInputSignalAdmin(admin.ModelAdmin):
list_display = ('name', 'author', 'input_file' )
admin.site.register(UserInputSignal, UserInputSignalAdmin)
Add this code in Admin.py if its not there.

Django to clear data causing save() prohibited to prevent data loss due to unsaved related object

I need to know how to clear the unsaved related data which causes the following error:
save() prohibited to prevent data loss due to unsaved related object 'order'.
My code is working as intended, but I failed to complete an order. Ever since this, any attempt to save a new order results in above error. I am aware of the cause being the changes to django.db.models.base.py, but there must be some way to clear this via logs or something...
I have tried recreating the database, and also the sqlflush command but neither is working.
VIEWS
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
import weasyprint
from django.shortcuts import render, redirect, get_object_or_404
from django.contrib.admin.views.decorators import staff_member_required
from django.core.urlresolvers import reverse
from django.conf import settings
from django.http import HttpResponse
from django.template.loader import render_to_string
from .models import OrderItem, Order
from .forms import OrderCreateForm
from cart.cart import Cart
from .tasks import order_created
# Create your views here.
#staff_member_required
def admin_order_detail(request, order_id):
order = get_object_or_404(Order, id=order_id)
return render(request, 'admin/orders/order/detail.html', {'order': order})
#staff_member_required
def admin_order_pdf(request, order_id):
order = get_object_or_404(Order, id=order_id)
html = render_to_string('orders/order/pdf.html', {'order': order})
response = HttpResponse(content_type='application/pdf')
response['Content-Disposition'] = 'filename="order_{}.pdf"'.format(order.id)
weasyprint.HTML(string=html).write_pdf(response, stylesheets=[weasyprint.CSS(settings.STATIC_ROOT + 'css/pdf.css')])
return response
def order_create(request):
cart = Cart(request)
if request.method == 'POST':
form = OrderCreateForm(request.POST)
if form.is_valid():
order = form.save(commit=False)
if cart.coupon:
order.coupon = cart.coupon
order.discount = cart.coupon.discount
order.save()
for item in cart:
OrderItem.objects.create(order=order, product=item['product'], price=item['price'], quantity=item['quantity'])
#emptying the cart
cart.clear()
#launch celery async task
order_created.delay(order.id)
request.session['order_id'] = order.id #set order.id session
return redirect(reverse('payment:process'))
else:
form = OrderCreateForm()
return render(request, 'orders/order/create.html', {'cart': cart, 'form':form})
MODELS
class Order(models.Model):
first_name = models.CharField(_('first_name'),max_length=50)
last_name = models.CharField(_('last_name'),max_length=50)
email = models.EmailField(_('email'),)
address = models.CharField(_('address'),max_length=250)
postal_code = models.CharField(_('postal_code'),max_length=250)
city = models.CharField(_('city'),max_length=100)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False)
coupon = models.ForeignKey(Coupon, related_name='orders', null=True, blank=True)
discount = models.IntegerField(default=0, validators=[MinValueValidator(0), MaxValueValidator(100)])
class Meta:
ordering = ('-created',)
def __unicode__(self):
return 'Order {}'.format(self.id)
def get_total_cost(self):
total_cost = sum(item.get_cost() for item in self.items.all())
return total_cost - total_cost *(self.discount)
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='items')
product = models.ForeignKey(Product, related_name='order_items')
price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.PositiveIntegerField(default=1)
def __unicode__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price * self.quantity
FORMS
from django import forms
from .models import Order
class OrderCreateForm(forms.ModelForm):
class Meta:
model = Order
fields = ['first_name', 'last_name', 'email', 'address', 'postal_code', 'city']
If you check your models, then you can see that the coupon field in the order table is a foreign key, in other words, a related object.
Because you don't save the coupon object, it doesn't have a pk and can't be added to the order. First save the coupon object, and then add it to the order.
So something like:
coupon = cart.coupon # not sure if this in between step is needed
coupon.save()
order.coupon = coupon
order.save()
SOLVED
simply save the order object a little earlier in the code so within the orders.views.py file, within the create_order() method, add an earlier invocation of order.save() ...
THIS
if form.is_valid():
order = form.save(commit=False)
BECOMES
if form.is_valid():
order = form.save(commit=False)
order.save()
if cart.coupon:
............
..............
All working fine again!!
#Snackoverflow thks for all your help :-)