So I am trying to print out a field in my models.py file to a HTML file. (I couldn't think of any other word besides print). I am able to do it for the username, but I am struggling for the description/bio in this case.
I have tried things like self.user.bio, self.userprofileinfo.bio among other things
models.py relevant class
class UserProfileInfo(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
first_name = models.CharField(max_length=50,blank=True,null=True)
last_name = models.CharField(max_length=50,blank=True,null=True)
bio = models.CharField(max_length=150)
image = models.ImageField(upload_to='profile_pics',default='default.png')
joined_date = models.DateTimeField(blank=True,null=True,default=timezone.now)
verified = models.BooleanField(default=False)
def __str__(self):
return self.user.username
def save(self, *args, **kwargs):
super().save(*args, **kwargs)
img = Image.open(self.image.path)
if img.height > 300 or img.width > 300:
output_size = (300, 300)
img.thumbnail(output_size)
img.save(self.image.path)
forms.py
class UserForm(forms.ModelForm):
password = forms.CharField(widget=forms.PasswordInput())
class Meta():
model = User
fields = ('username','email','password')
class UserProfileInfoForms(forms.ModelForm):
class Meta():
model = UserProfileInfo
fields = ('first_name','last_name','bio','image')
user_posts.html
{% extends 'mainapp/base.html' %}
{% block content %}
<div class="sidebar">
<p class="active" href="#">{{ view.kwargs.username }}</p>
<p>{{ view.kwargs.bio }}</p>
<p>Lorem</p>
<p>Lorem</p>
</div>
{% for post in posts %}
<div class="content">
<div class="post">
<h1 class='posttitle'>{{ post.title }}</h1>
{% if post.published_date %}
<!-- <div class="postdate">
<i class="fas fa-calendar-day"></i> <p>Posted {{ post.published_date|timesince }} ago</p>
</div> -->
<div class="posted-by">
<p>Posted by <strong>{{ post.author }}</strong> {{ post.published_date|timesince }} ago</p>
</div>
{% else %}
<a class="pub-post" href="{% url 'mainapp:post_publish' pk=post.pk %}">Publish</a>
{% endif %}
<p class='postcontent' >{{ post.text|safe|linebreaksbr }}</p>
</div>
</div>
{% endfor %}
{% endblock %}
I tried this code right here:
return '%s %s' % (self.user.username, self.UserProfileInfo.bio)
However this did not work, and it didn't print anything off in the HTML. Thanks for any help :)
This is my views.py UserPostListView. I just realised I didn't have bio there. How would I be able to add multiple strings? Comma separated?
class UserPostListView(ListView):
model = Post
template_name = 'mainapp/user_posts.html'
context_object_name = 'posts'
def get_queryset(self):
user = get_object_or_404(User,username=self.kwargs.get('username'))
return Post.objects.filter(author=user).order_by('-published_date')
Related
I have two seperated models. One with two text fields and one for multiple images. Now I want to display the entire data in one html div. What do I have to change in the projects view and in projects.html?
models.py
class Project(models.Model):
title = models.CharField(max_length=200)
describtion = models.TextField(null=True, blank=True)
class ProjectImage(models.Model):
project = models.ForeignKey(Project, on_delete=models.CASCADE)
image = models.FileField(upload_to="products/")
forms.py
class ProjectForm(forms.ModelForm):
class Meta:
model = Project
fields = ['title', 'describtion']
class ProjectImageForm(forms.ModelForm):
class Meta:
model = ProjectImage
fields = ['image']
widgets = {
'image': ClearableFileInput(attrs={'multiple': True}),
}
views.py
def createProject(request):
form = ProjectForm()
form2 = ProjectImageForm()
if request.method == 'POST':
form = ProjectForm(request.POST)
form2 = ProjectImageForm(request.POST, request.FILES)
images = request.FILES.getlist('image')
if form.is_valid() and form2.is_valid():
title = form.cleaned_data['title']
describ = form.cleaned_data['describtion']
project_instance = Project.objects.create(
title=title, describtion=describ)
for i in images:
ProjectImage.objects.create(project=project_instance, image=i)
context = {'form': form, 'form2': form2}
return render(request, 'projects/project_form.html', context)
def projects(request):
projects = Project.objects.all()
context = {"projects":projects}
return render(request, 'projects/projects.html', context)
projects.html
{% for project in projects %}
<div class="column">
<div class="card project">
<img class="project__thumbnail" src="{{project.image.url}}" alt="project thumbnail" />
<div class="card__body">
<h3>{{project.title}}</h3>
<h2>{{project.describtion}}</h2>
</div>
</a>
</div>
</div>
{% endfor %}
You don't need to change anything.
You should be able to access the reverse with project.project_image_set attribute in the template:
<div class="card__body"
<h3>{{project.title}}</h3>
<h2>{{project.describtion}}</h2>
{% for image in project.project_image_set.all %}
{{ image.image }}
{% endfor %}
</div>
Docs: https://docs.djangoproject.com/en/4.0/topics/db/examples/many_to_one/
I don't really understand the question here but i see a problem in your template considering you are using foreign key in ProjectImage. And update the question
{% for project in projects %}
<div class="column">
<div class="card project">
{% for j in project.projectimage_set.all %}
<img class="project__thumbnail" src="{{j.image.url}}" alt="project thumbnail" />
{% endfor %}
<div class="card__body">
<h3>{{project.title}}</h3>
<h2>{{project.describtion}}</h2>
</div>
</a>
</div>
</div>
{% endfor %}
I would change FileField to ImageField and add function:
#property
def get_photo_url(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return ''
If createProject function works( I would rename it to create_project) then in projects.html:
{% for project in projects %}
<div class="column">
<div class="card project">
<div class="card__body">
<h3>{{project.title}}</h3>
<h2>{{project.describtion}}</h2>
{% for img in project.projectimage_set.all %}
<img class="project__thumbnail" src="{{img.get_photo_url}}" alt="project thumbnail" />
{% endfor %}
</div>
</a>
</div>
</div>
{% endfor %}
so i want to khow what i have to add in the urls.py and in the views.py to add this functionnality: if i click in one of this categories here my categories display some products based on the category chosen.
and this the models.py
class Product(models.Model):
name=models.CharField(max_length=200,null=True)
price=models.DecimalField(max_digits=7,decimal_places=2)
digital=models.BooleanField(default=False,null=True,blank=True)
image=models.ImageField(blank=True,null=True,upload_to ='images/',default="images/default.jpg")
categories = models.ForeignKey(Category,on_delete=models.CASCADE,blank=True, null=True)
def __str__(self):
return self.name
#property
def imageURL(self):
if self.image and hasattr(self.image, 'url'):
return self.image.url
else:
return '/static/images/default.png'
class Category(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField(max_length=50, unique=True,
help_text='Unique value for product page URL, created from name.')
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
db_table = 'categories'
ordering = ['-created_at']
verbose_name_plural = 'Categories'
def __unicode__(self):
return self.name
and this is the template :
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<form method="get" action="">
{% for c in active_categories %}
<a class="dropdown-item" href='#'>{{ c.name }}</a>
{% endfor %}
<a class="dropdown-item" href="#">something else</a>
</form>
</div>
This is simplest way. You can change code as per requirement.
urls.py
from . import views # import views.py file
urlpatterns = [
path('product_list/<id>', views.product_list, name='product_list'),
]
views.py
def product_list(request, id):
products = Product.objects.filter(categories__pk=id)
context = {
'products': products,
}
return render(request, 'product_list.html', context)
link template (Check the change in link)
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<form method="get" action="">
{% for c in active_categories %}
<a class="dropdown-item" href="{% url 'product_list' id=c.pk %}">{{ c.name }}</a>
{% endfor %}
<a class="dropdown-item" href="#">something else</a>
</form>
</div>
product_list.html
Your regular html things +
{% for product in products %}
<p>{{ product.name }}</p>
<p>{{ product.price }}</p>
{% empty %} # in case there is no product in this category
<p>No product available for this category</p>
{% endfor %}
I hope this will help. Please comment if get any error.
If you products to load without refreshing the page, you can use ajax. Reply if need that.
You can try this:
views.py
def my_view(request):
category_id = request.GET.get('category_id')
context = {}
if category_id:
products = Product.objects.filter(categories__id=category__id)
context["products"] = products
return render(request, 'template', context)
template
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<form method="get" action="">
{% for c in active_categories %}
<a class="dropdown-item" href='?category_id={{ c.id }}'>{{ c.name }}</a>
{% endfor %}
<a class="dropdown-item" href="#">something else</a>
</form>
</div>
I have created a Job model that contains Member and Manager info. It looks great imo. I created a class based view that translates the job if the user has one. Right now it's not showing. It just shows as a blank with an empty image file. I don't know what I did wrong or if I mistakenly used the wrong variables in the html file.
Here's my views.py:
from django.shortcuts import render
from django.views.generic import ListView, CreateView
from .models import Job
from profiles.models import User
# Create your views here.
class jobs(ListView):
model = Job
template_name = 'users/user_jobs.html'
context_object_name = 'jobs'
def get_queryset(self):
return Job.objects.filter(member__member=self.request.user)
class createjob (CreateView):
model = Job
fields = ['member','title', 'description', 'file'
My Models.py:
from django.db import models
from profiles.models import User
# Create your models here.
class Points (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
points = models.IntegerField(default=0, null=False)
def __str__(self):
return self.user.username
class Profile (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
image = models.ImageField(default='default.png',upload_to='profile_pics')
def __str__(self):
return f'{self.user.username}Profile'
class Manager (models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
manager = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name
class Member (models.Model):
name = models.CharField(max_length=30, blank=True, null=True)
manager = models.ForeignKey(Manager, on_delete=models.CASCADE)
member = models.ForeignKey(User,on_delete=models.CASCADE)
def __str__(self):
return self.name
class Job (models.Model):
manager = models.OneToOneField(Manager, on_delete=models.CASCADE)
member = models.OneToOneField(Member, on_delete=models.CASCADE)
title = models.CharField(max_length=30, blank=False, null=False)
description = models.TextField()
datePosted = models.DateTimeField (auto_now = True)
file = models.FileField(null=True, blank=True,upload_to='job_files')
def __str__(self):
return self.title
And user_jobs.html:
{% extends "profiles/base.html" %}
{% block content %}
<article class="media content-section">
<img class="rounded-circle article-img"src="{{ jobs.manager.profile.image.url}}">
<div class="media-body">
<div class="article-metadata">
<a class="mr-2" href="#">{{ objects.job.Manager }}</a>
<small class="text-muted">{{jobs.datePosted|date:"F d, Y" }}</small>
</div>
<h2><a class="article-title" href="#">{{ jobs.title }}</a></h2>
<p class="article-content">{{ jobs.description }}</p>
</div>
</article>
{% if is_paginated %}
{% if page_obj.has_previous %}
<a class="btn btn-outline-info mb-4"href="?page=1"> First</a>
<a class="btn btn-outline-info mb-4"href="?page={{ page_obj.previous_page_number }}"> Previous</a>
{% endif %}
{% for num in page_obj.paginator.page_range %}
{% if page_obj.number == num %}
<a class="btn btn-outline-info mb-4"href="?page={{ num }}"> {{ num }}</a>
{% elif num > page.obj.number|add:'-3' or num < page.obj.number|add:'3' %}
<a class="btn btn-outline-info mb-4"href="?page={{ num }}"> {{ num }}</a>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<a class="btn btn-outline-info mb-4"href="?page={{ page_obj.next_page_number }}"> Next </a>
<a class="btn btn-outline-info mb-4"href="?page={{ page_obj.paginator.num_pages }}"> Last </a>
{% endif %}
{%endif%}
{% endblock content %}
TIA for the help guys.
you have to loop through the object list output in your list template to see the out put
{% for object in jobs %}
{{ object.title }}
{% endfor %}
I can not get my form data to commit to my sqlite3 database. I don't see any errors. I can commit data through admin, but not through my own controller using form. I've tried many diff. combos and still no success. I would like to use class based view, please. Everything works, the form just won't save the data to database. There are no errors.
url: url(r'^create/$', CreateRequest.as_view())
forms.py:
class CreateForm(ModelForm):
date_due = forms.DateTimeField(widget=widgets.AdminSplitDateTime)
class Meta:
model = Request
fields = ['region', 'user_assigned', 'user_requester', 'description']
views.py:
class CreateRequest(LoginRequiredMixin, CreateView):
model = Request
fields = ['region', 'user_assigned', 'user_requester', 'date_due', 'description']
template_name = "requests_app/createRequest.html"
form_class = CreateForm
success_url = '/'
def form_valid(self, form):
objects = form.save()
return super(CreateRequest, self).form_valid(form)
models.py:
class Request(models.Model):
region = models.ForeignKey(Region)
completed = models.BooleanField(default=False)
user_assigned = models.ForeignKey(settings.AUTH_USER_MODEL, null=True, blank=True, related_name='user_assigned')
user_requester = models.ForeignKey(settings.AUTH_USER_MODEL, related_name='user_requester')
date_due = models.DateTimeField()
date_completed = models.DateTimeField(null=True, blank=True)
description = models.CharField(max_length=500)
objects = models.Manager()
open_requests = OpenRequests()
completed_requests = CompletedRequests()
def mark_completed(self):
if not self.completed:
self.completed = True
self.date_completed = datetime.datetime.now()
index.html:
<h1>hi</h1>
<form action="/create/" method="post">
{% csrf_token %}
{{ form.non_field_errors }}
<div class="fieldWrapper">
{{ form.region.errors }}
<label for="id_region">Region</label>
{{ form.region }}
</div>
<div class="fieldWrapper">
{{ form.user_assigned.errors }}
<label for="id_user_assigned">User Assigned</label>
{{ form.user_assigned }}
</div>
<div class="fieldWrapper">
{{ form.user_requester.errors }}
<label for="id_user_requester">user_requester: </label>
{{ form.user_requester }}
</div>
<div class="fieldWrapper">
<p> {{ form.date_due.errors.as_text }} </p>
<label for="id_date_due">Due Date</label>
{{ form.date_due }}
</div>
<div class="fieldWrapper">
{{ form.description.errors }}
<label for="id_description">Descr.</label>
{{ form.description }}
</div>
<p><input type="submit" value="Submit Request" /></p>
{% if form.non_field_errors %}
{% for err in form%}
<div class="fieldWrapper">
<p class="form-error">{{ err }}</p>
<p class="form-error">{{ err.label_tag }} {{ field }}</p>
</div>
{% endfor %}
{% endif %}
</form>
{% endblock %}
in views.py you don't need this line: objects = form.save()
It can be
class ContaktCreateView(CreateView):
model = Contakt
form_class = ContaktForm
template_name = "www/www_contakt.html"
success_url = '/thanks/'
def form_valid(self, form):
return super(ContaktCreateView, self).form_valid(form)
Also I'm not using action in form action="/create/" method="post"
You are calling this html form via your line in urls.py:
url(r'^create/$', CreateRequest.as_view())
which is using your CreateRequest view which is using your index.html form file.
I am trying to use Taggit for users to be able to tag their posts while they are submitting a form. But I can successfully let them type manually(their tags), I am trying to change to check boxes. Any ideas?
forms.py
class TalesForm(ModelForm):
class Meta:
model = Tale
fields = ('title', 'body', 'tags')
m_tags = TagField()
models.py
class Tale(models.Model):
title = models.CharField(max_length = 50)
body = models.TextField(max_length = 10000)
pub_date = models.DateTimeField(default = datetime.now)
poster = models.CharField(max_length = 30)
tags = TaggableManager()
def __unicode__(self):
return self.title
views.py
def add(request):
if request.user.is_authenticated():
if request.method=='POST':
form=TalesForm(request.POST)
if form.is_valid():
m_tags = form.cleaned_data['tags']
newTale=Tale(title=form.cleaned_data['title'], body=form.cleaned_data['body'], poster = request.user)
newTale.save()
for m_tag in m_tags:
newTale.tags.add(m_tag)
#form.save_m2m()
return HttpResponseRedirect('/home/%s'%newTale.id)
else:
return render_to_response('story/add.html', {'form':form}, context_instance=RequestContext(request))
else:
form=TalesForm()
args = {}
args.update(csrf(request))
args['form'] = form
context= {'form': form}
return render_to_response('story/add.html',context, context_instance=RequestContext(request))
else:
return HttpResponseRedirect('/home')
html
<form method="post" action="/home/add/">
{% csrf_token %}
<div class="register_div">
{% if form.title.errors %}<p class="error" >{{ form.title.errors }}</p>{% endif %}
<p><label for="title"{% if form.title.errors %} class="error"{% endif %}>Title:</label></p>
<p>{{ form.title}}</p>
</div>
<div class="register_div">
{% if form.body.errors %}<p class="error" >{{ form.body.errors }}</p>{% endif %}
<p><label for="body"{% if form.body.errors %} class="error"{% endif %}>Body:</label></p>
<p>{{ form.body }}</p>
</div>
<div class="register_div">
<p><label for="tag">Tags:</label></p>
<p>{{ form.tags }}</p>
</div>
<input type="submit" value="Add Story" name="submit" />
</form>
Define your form this way:
from taggit.models import Tag
class TalesForm(ModelForm):
tags = forms.ModelMultipleChoiceField(queryset=Tag.objects.all(),
widget=forms.CheckboxSelectMultiple())
class Meta:
model = Tale
fields = ('title', 'body', 'tags')