Django author Form not saving to database - python-3.x

models.py
class Blog(models.Model):
title = models.CharField(max_length=100, unique=True)
slug = models.CharField(max_length=100, unique=True)
post_pic = models.ImageField(upload_to ='media/post_pics/', default =None )
body = models.TextField()
posted = models.DateTimeField(db_index=True, auto_now_add=True)
#author = must be logged in, populate from login details
forms.py
class postForm(forms.Form):
title = forms.CharField(max_length=100)
slug = forms.CharField(max_length=100)
post_pic = forms.ImageField()
body = forms.CharField(widget=SummernoteWidget())
views.py
def write_detail(request):
template_name = 'blog/write.html'
if request.method == 'POST':
post_form = postForm(request.POST)
if post_form.is_valid():
new_post = Blog(title=title,slug=slug,post_pic=post_pic,body=body)
new_post.save()
return HttpResponseRedirect(blog.get_absolute_url())
else:
post_form = postForm()
return render(request, template_name, {'post_form': post_form})
write.html
{% extends 'blog/base.html' %}
{% load static %}
{% block back-img %}'{% static 'blog/assets/img/intro.jpg' %}'{% endblock back-img %}
{% block titdes %}Write{% endblock titdes %}
{% block title %}Write{% endblock title %}
{% block pagedes %}A django powered community blog{% endblock pagedes %}
{% block body%}
<form method = "POST">
{{ post_form.as_p }}
{% csrf_token %}
<button type="submit" class="btn btn-primary">Publish</button>
</form>
{% endblock %}
I have set up this form so that authors can write articles to the blog without accessing the admin panel and I believe it should work but it isn't saving to the database.
I have tried to work on the views over and over but don't know what else to do. Please don't delete my question just ask any question that can help you help me.

in your forms.py
try
from .models import Blog
class postForm(forms.Form):
title = forms.CharField(max_length=100)
slug = forms.CharField(max_length=100)
post_pic = forms.ImageField()
body = forms.CharField(widget=SummernoteWidget())
class Meta:
model = Blog
fields = ('title', 'slug', 'post_pic', 'body')
PS. Iam new to Django, i hope this help you.

It looks like you just need to save the form, but you're creating a new Blog object with values that we can't see defined anywhere.
new_post = Blog(title=title,slug=slug,post_pic=post_pic,body=body)
title, slug, etc don't get defined.
What you should do, is change it to a ModelForm so that django does all the hard work;
class postForm(forms.ModelForm):
class Meta:
model = Blog
fields = ('title', 'slug', 'post_pic', 'body')
widgets = {
'body': SummernoteWidget(),
}
Then in your view you just need to do;
def write_detail(request):
template_name = 'blog/write.html'
if request.method == 'POST':
post_form = postForm(request.POST)
if post_form.is_valid():
post_form.save()
return HttpResponseRedirect(blog.get_absolute_url())
else:
# GET request
post_form = postForm()
return render(request, template_name, {'post_form': post_form})
The summernote docs for forms (and modelforms) is here
Don't forget, that when using a widget like this that comes with media, you need to add the form's media to the template.
You can access it in the HTML using either {{ form.media }} to get all CSS and JS, or individually as {{ form.media.js }} and {{ form.media.css }}
You can see how they do it in the summernote app playground

class postForm(forms.ModelForm):
class Meta:
model = Blog
fields = ('title', 'slug', 'post_pic','body')
widgets = {
'body':SummernoteWidget(),
}
Sorry guys you can actually use django summer note with a model form. I used it before but the editor was not appearing so I changed it to the one I previously posted but after reading another answer on stack overflow. I found out that I didn't add this code below to my HTML files or just inside my base.html
<!-- include summernote css/js-->
<link href="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.3/summernote.css" rel="stylesheet">
<script src="http://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.3/summernote.js"></script>
Thanks guys

Related

display images in djangoi template from database in Django3

Here i am using Django 3 and Python 3.7 where i want to display the the signature as image in my html page
Here is my views.py
def jobsignature_view(request, pk):
job = CreateJob.objects.filter(id=pk)
job_data={}
for val in job_id:
job_data['job_id'] = pk
job_data['signature'] = val.signature
......
....
Here is my models.py
class Cre(models.Model):
signature = models.TextField(default='', blank=True, null=True)
here in my database it is saving as
id signature
1 b'b3V0cHV0'
Here is my template.html
I confirm that this work has been completed:
<div class="span12">
{{ form.media }}
{% if job_data.signature != None and job_data.signature != '' %}
<img src="data:image/png;base64,{{job_data.signature}}"/>
{% endif %}
</div>
here is how its is displaying
How can i make my signature display here please help me
In your life I think for a search on a primary key it is more appropriate to use get(), your primary key is unique, we expect only one object. Filter() is used to return a queryset of otherwise multiple items :
def jobsignature_view(request, pk):
job = CreateJob.objects.get(id=pk)
return render(request, 'myapp/yourpage.html', {'job': job})
In the html template :
{% if job %}
<img src="{{job.signature}}"/>
{% endif %}
For the model I think you should use ImageField :
from django.core.files.storage import FileSystemStorage
from django.db import models
fs = FileSystemStorage(location='/media/photos')
class CreateJob(models.Model):
...
signature = models.ImageField(storage=fs)

Best way to filter on data belonging to the logged in user (Django)

First of all; I'm fairly new to Django.
Right now, I'm trying to create a very simple webpage with links (just to learn). The idea right now is, that a user (which is logged in) can add links to the database/model, and only see the links of which he has added.
I'm strugling to figure out what the best practice is for that - is it to store the user.username in the model, and then make a .filter(username=user) each time or..? I would assume Django has some (faster way) of handling this.
I have the following
models.py
from django.db import models
from django.contrib.auth.models import User
class links(models.Model):
link = models.URLField()
#user = <something_here>
views.py
def add_link(request):
if request.method == "POST":
form = add_link_form(request.POST)
if form.is_valid():
messages.success(request, "Link is added!")
form.save()
return redirect("my_links")
else:
form = add_link_form()
context = {
"links":links.objects.all(),
"form":form
}
return render(request, "django_project/my_links.html",context=context)
my_links.html
{% extends "django_project/base.html" %}
{% load crispy_forms_tags %}
{% block content %}
<div class="content-section">
<form method="POST">
{% csrf_token %}
{{form|crispy}}
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Add link</button>
</div>
</form>
{% for l in links%}
{{l.link}}
{% endfor%}
{% endblock content %}
You can define Link as:
class Link(models.Model):
link = models.URLField()
user = models.ForeignKey(settings.AUTH_USER_MODEL, related_name="links")
where, when adding you could do:
logged_in_user.links.create(...)
or if adding an already existing link:
logged_in_user.links.add(link)
or if you know that links will forever remain as as strings without any other data related to it, and you use postgresql as your DB, you could add this field to the user model:
from django.contrib.postgres.fields import ArrayField
from django.db import models
class UserModel(models.Model):
...
links = ArrayField(models.URLField(), default=list)
and when adding, treat it exactly as you would do with an array:
logged_in_user.links.append("google.com")
logged_in_user.save()
Both of these approaches, in essence, provide you a filtered list when calling logged_in_user.links, but in the first case it is a queryset of Link objects, whereas the second is an array of strings.

Upload image in Django for specific user

I am trying to upload pic for specific user but nothing happened when i select image and upload it . it not store in db and not even in media folder
setting.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media/')
MEDIA_URL = '/media/'
View.py
def uploadPic(request):
if request.method == 'POST' and 'SESSION_KEY' in request.session:
form = Profile(
user_id=request.session['SESSION_KEY'],
profile_pic=ProfileForm(request.POST, request.FILES)
)
form.save()
return redirect('home')
else:
form = ProfileForm()
return render(request, 'upload.html', {
'form': form
})
Model.py
class Profile(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile_pic = models.ImageField(null=True, blank=True, upload_to='image/')
Form.py
class ProfileForm(forms.ModelForm):
class Meta:
model = ProfileModel
fields = ['profile_pic']
Template
{% extends 'home.html'%}
{% block content %}
{%if user.is_authenticated%}
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Upload</button>
</form>
{% endif %}
{% endblock %}
Firstly in your form you set model = ProfileModel but your model is Profile correct that:
class ProfileForm(forms.ModelForm):
class Meta:
model = Profile
fields = ['profile_pic']
Next in your view in case of a POST request your view is completely wrong. You try to make an instance of Profile and call it form and save it. This is likely failing. Also I assume you write 'SESSION_KEY' in request.session in an attempt to check if the user is logged in, instead use request.user.is_authenticated or in fact disallow anonymous users from accessing your views by using the login_required decorator. Change it like so:
from django.contrib.auth.decorators import login_required
#login_required
def uploadPic(request):
if request.method == 'POST':
form = ProfileForm(request.POST, request.FILES)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('home')
else:
form = ProfileForm()
return render(request, 'upload.html', {'form': form})
Note: The indentation of my answer is 4 spaces which is different from your indentation. It is best to indent by 4 spaces for readability. Check about indentation in PEP 8 which is the Style Guide for Python Code.

ModelForm Fields are not pre-populated with existing data during updating in Django

I want to update the User and Lab model. I am able to see the form but it is not pre-populated with existing database information even after setting the instance parameter. If I submit a blank form then all fields are reset to blank values in the database. I have tried several solutions available online but nothing works.
My queries -
How do I pre-populate my form with existing data?
If the user doesnt fill out a particular field, I want the previous information to be stored as it is and not as a blank value. How do I achieve this?
I have the following models.py
class Lab(models.Model):
uid = models.OneToOneField(User, on_delete=models.CASCADE)
company=models.CharField(max_length=200,blank=True)
#receiver(post_save, sender=User)
def create_lab_profile(sender, instance, created, **kwargs):
if created:
Lab.objects.create(uid=instance)
#receiver(post_save, sender=User)
def save_lab_profile(sender, instance, **kwargs):
instance.lab.save()
Forms.py
class UserForm(forms.ModelForm):
email=forms.EmailField(max_length=300)
class Meta:
model = User
fields = ('first_name', 'last_name', 'email',)
class LabForm(forms.ModelForm):
class Meta:
model = Lab
fields = ('company',)
views.py
#login_required
def update_user_details(request,pk):
if request.method == 'POST':
user_form = UserForm(request.POST,instance=request.user)
lab_form = LabForm(request.POST,instance=request.user.lab)
if user_form.is_valid() and lab_form.is_valid():
user_form.save()
lab_form.save()
messages.success(request,'Your profile was successfully updated!')
return redirect('user_details')
else:
messages.error(request,('Please correct the error below.'))
else:
user_form = UserForm(instance=request.user)
lab_form = LabForm(instance=request.user.lab)
return render(request, 'update_user_details.html', {'user_form': user_form,'lab_form': lab_form})
template -
{% extends 'base.html' %}
{% block content %}
{% csrf_token %}
<H3> Update Personal information - </H3>
<br>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{{ user_form.as_p }}
{{ lab_form.as_p }}
<button type="submit" class="btn btn-primary">Save changes</button>
</form>
{% endblock %}
Any help/suggestions will be appreciated!

Django: get user related field value in HTML to

I am trying to show the related field of the user on the webpage using Django.
I have models:
Models.py
class Companies(models.Model):
company_name = models.TextField()
company_email = models.EmailField()
company_owner = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.company_name
class Cars(models.Model):
company = models.ForeignKey('Companies', on_delete=models.CASCADE)
car_model = models.TextField()
views.py:
class UserCompanyCars(ListView):
model = Cars
template_name = 'home/company_cars.html'
context_object_name = 'cars'
slug_field ="username"
paginate_by = 100
def get_queryset(self):
company_n = get_object_or_404(Companies, company_owner=self.request.user)
return Cars.objects.filter(company=company_n)
and my html is:
{% extends 'home/base.html' %}
{% block content %}
<h1 class="mb-3"> Cars of {{user.Companies.company_name}}</h1>
{% for car in cars %}
<div class="media-body">
<div class = "article-metadata">
<p class="article-content">{{car.company}}</p>
{{car.car_model}}
<p class="article-content">{{car.car_carry }}</p>
</div>
</div>
{% endfor %}
{% endblock content %}
What I am trying to achieve is to write out "Cars of TestCompany (26)" on the webpage, but I cannot figure out how to get the Company_Name which is owned by the user. I have been trying all those Companies.objects... variations but none of them seem to work.
Try this (sample code taken from my project):
category = get_object_or_404(Category, pk=self.kwargs['pk'])
context['allcategories'] = MyPosts.objects.filter(category=category)
return context
This will filter all posts in the database based on certain categories. You can apply the same solution to your code.
If this solution does not work, please try to give more details about the problem.

Resources