How to hyperlink data from database on django - html

I am trying to build a simple search function on django that leads me to the link when I click on it. (I know API links are JSON links so clicking on them gives you no output of value but the point is to be able to click on them)
i tried using but it doesn't work
from my results.html:
{% for dataset in datasets %}
<br/>
{{ dataset.datasets_available }}
<br/>
{{ dataset.data_source }}
<br/>
{{ dataset.brief_description_of_datasets }}
<br/>
{{ dataset.country }}
<br/>
<a href='https://www.google.com'>{{ dataset.api_documentation }}<a>
<br/> #^ is the part i wanna fix
<br/>
{% endfor %}
{% else %}
<p style="font-family:Cambria">No search results for this query</p>
{% endif %}`
from views.py:
def results(request):
query = request.GET.get('q')
if query:
datasets = api_data.objects.filter(Q(datasets_available__icontains=query))
context = {
'datasets': datasets,
}
return render(request, 'Search/results.html', context)
from models.py:
class api_data(models.Model):
data_source = models.TextField()
brief_description_of_data = models.TextField()
datasets_available = models.TextField()
brief_description_of_datasets = models.TextField()
country = models.TextField()
api_documentation = models.TextField()
class Meta:
verbose_name_plural = "api_data"
api_documentation is currently urls in strings. i want to be able to click on the output in html and view the actual website

I'm not sure what you're trying to do, but if the website URL is in the api_documentation field, then you need to make this field the href of your html anchor.
Something like this:
<a href='{{ dataset.api_documentation }}'>{{ dataset.api_documentation }}</a>

Related

Django/html issue with displaying/linking image

I'm making a site by using django. One of my models contains ImageField.
Files are saved in main_dir/media/images. I'd like to display specific images in templates but I can't achieve it. Instead of photo, I can see only default image icon which mean ( i guess ) that image is not found
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'
models
class Gallery(models.Model):
name = models.CharField(max_length=200)
author = models.ForeignKey(User, on_delete=models.CASCADE, default=None, null=True, blank=True)
date_posted = models.DateTimeField(auto_now_add = True)
def __str__(self):
return self.name
class Photo(models.Model):
gallery = models.ForeignKey(Gallery, on_delete=models.CASCADE, default=None, related_name='photos')
name = models.CharField(max_length=200)
description = models.TextField(blank=False)
image = models.ImageField(blank=True, upload_to='images')
views
def gallery(request, pk):
gallery_object = Gallery.objects.get(id=pk)
context = {'gallery':gallery_object}
return render(request, 'Gallery/gallery.html', context)
html
<!DOCTYPE html>
{% extends 'base.html' %}
{% block content %}
<h1>Gallery: {{ gallery.name }}</h1>
{% for photo in gallery.photos.all %}
<img src="{{photo.image.url}}">
<a>{{photo.image.url}}</a> #it's here only to check if path is correct
{% endfor %}
Go back to home page
{% endblock content %}
what should I change to display image correctly ?
you need to change the .get to .filter with the same condition to get multiple objects
because get will return 1 object only and you cant do the for loop in the template
There are a few things wrong. First of all, if you want to return multiple images then you have to use .filter() instead of .get() and if you are .get() instead of the filter then you don't have to loop over it as it is giving a single object. And the image is stored in Photos model and for that you will have to call that instead of gallery.
Here is how you can fix it:
For single object:
views function:
def gallery(request, pk):
gallery_object = Photos.objects.get(id=pk)
context = {'photo': photo_object}
return render(request, 'Gallery/gallery.html', context)
HTML template:
<!DOCTYPE html>
{% extends 'base.html' %}
{% block content %}
<h1>Gallery: {{ photo.name }}</h1>
<img src="{{photo.image.url}}">
<a>{{photo.image.url}}</a> #it's here only to check if path is correct
Go back to home page
{% endblock content %}
For returning multiple objects:
views function:
def gallery(request, pk):
gallery_object = Photos.objects.filter(#your query)
context = {'photos': photo_object}
return render(request, 'Gallery/gallery.html', context)
HTML:
<!DOCTYPE html>
{% extends 'base.html' %}
{% block content %}
{% for photo in photos %}
<h1>Gallery: {{ photo.name }}</h1>
<img src="{{photo.image.url}}">
<a>{{photo.image.url}}</a> #it's here only to check if path is correct
{% endfor %}
Go back to home page
{% endblock content %}
finally, i found an issue. I forgot about adding
urlpatterns+=static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)
to my urls.py file.
lmao

tags of content written by django_summernote is exposed, not applied

I start using Django for personal blog building, and just install django_summernote as an editor.
However when I get the text in html templets, the html tags of main articles are exposed, not applied properly. It looks like below.
Here is the main text.
Hellow World! First Post <h1><span style="font-family: Arial;">Hello,
World!</span></h1><p><span style="font-family: Arial;">This is my first
post.</span></p><p><br></p>
Where the templet is like below.
<div id="middle_canvas">
Here is the main text. <br>
{% for post in recent_posts %}
{{ post.title }}
{{ post.text }} <br><br>
{% endfor %}
</div>
Also, the Post model is like below.
class Post(models.Model):
author = models.ForeignKey('auth.User', on_delete=models.CASCADE)
title = models.CharField(max_length=200)
text = models.TextField()
created_date = models.DateTimeField(
default=timezone.now)
published_date = models.DateTimeField(
blank=True, null=True)
def publish(self):
self.published_date = timezone.now()
self.save()
def __str__(self):
return self.title
I have no idea where to check.
Solved I used safe filter like below.
{{post.title | safe}}

how to extract images for every single post in django

I have two different models. One is for posts and other one is for images.
what I want is to display all images for every single post. Here is the file for models:
class Cars_Posts(models.Model):
user = models.ForeignKey(MyUser, on_delete=models.CASCADE)
post_city = models.ForeignKey(City, on_delete=models.CASCADE)
post_title = models.CharField(max_length=256)
post_detail = models.TextField(max_length=65536)
price = models.PositiveIntegerField()
def __str__(self):
return "%s %s %s %s %s"(
self.user.id, self.post_city,
self.post_title, self.post_detail, self.price,)
class Images_Cars(models.Model):
post = models.ForeignKey(Cars_Posts, on_delete=models.CASCADE)
car_images = models.ImageField(upload_to='car_images', blank=True, null=True )
def __str__(self):
return "%s %s " % (self.post_id, self.car_images, )
Here is the view FUNCTION FOR SEARCH (QUERY DATA BASE):
def search(request):
template = 'path/to/template.html'
# get all cities in data base
all_p_cities = City.objects.all()
#get the exact city selected by user and passed through the variable h_qc
query_c = request.GET.get('h_qc')
# get posts under the selected city
result = Cars__Posts.objects.filter(Q(post_city__city_name__iexact=query_c)
# get posts IDs of the result object
p_id=[]
for item in result:
p_id+= [item.id]
# print(p_id)
#get all images under each single post
all_images=[]
for item in p_id:
images = Images_Cars.objects.filter(post_id = item)
all_images+=[images]
# print (p_id)
# print(result)
print(all_images)
context = {
'post_city' : query_c,
'result': result,
'all_images':all_images,
}
return render(request, template, context )
both files run with no error. However in the template I want to display all posts and all images for every single post. I need your help in here. I looped over results and could get all posts. But I got also all images for every single posts repeated in every loop. So , instead of getting only images related to the current post, I got all images for all posts in current post and all subsequent posts. Any help or suggestion will be appreciated. Also any suggestion for writing the code in view file with an efficient and sophisticated way is appreciated.
Here is portion of the HTML File:
{% csrf_token %}
{% for item in result %}
<li class="result-row">
<!-- image box -->
<span>
<a href="#" class="result-image-act" >
{% for image in all_images %}
<!-- if image list is empty display the default image -->
{% if not image %}
<img src="{% static 'path/to/default image' %}" class="active">
{% endif %}
<!-- I have class ="active" which is supposed to be class of first image -->
{% if image and image.0 %}
<img class="active" src="{{image.item.car_images.url}}" >
{% elif image and not image.0 %}
<img src="{{image.item.car_images.url}}" >
{% endif %}
{% endfor %}
</a>
<span class="embed-result-price">{{item.price}}</span>
<div class="swipe-wrap">
<div class="swipe-wrap-lef">
<span class="move" >
<div class="swipe-prev">
<p><</p>
</div>
</span>
</div>
<div class="swipe-wrap-rig">
<span class="move" >
<div class="swipe-next">
<p>></p>
</div>
</span>
</div>
</div>
</span>
<span class="result-price">{{result.price}}
</span>
<span class="result-price">{{result.title}}</span>
</li>
{% endfor %}
Note: inside the html javascript code that will take care of swipe images for every single post that is why I fetch for the first image for every single post to add class="active" to it
You can do it directly in templates with reverse related name:
add a property method in your ImageCars model to check whether files are actually exist
class Images_Cars(models.Model):
''' code '''
car_images = models.ImageField(upload_to='car_images', blank=True, null=True )
#property
def car_images_exists(self):
return self.car_images.storage.exists(self.car_images.name)
templates
{% for item in result %}
{% for image in item.images_cars_set.all %}
#<!-- The images_cars instance is here -->
{% if image.car_images_exists %} # see changes in models
{{image.car_images.url}}
{% endif %}
{% empty %}
#<!--Item has no image_cars instances here: item.images_cars_set.all -->
<h3>No Images</h3>
{% endfor %}
{% endfor %}
You don't really need to loop through the queryset in views and again in templates
result as template variable is enough to have everything in templates

How to remove <br/> tag from Textarea?

I'm using Django to construct a simple personal website. I just built a basic email form. Here's the models.py file for it:
from django.db import models
class Message(models.Model):
name = models.CharField(max_length=200, unique=True)
email = models.EmailField(unique=True)
subject = models.CharField(max_length=100, unique=True)
message = models.CharField(max_length=1000, unique=True)
def __unicode__(self):
return self.name
And here is the corresponding forms.py file:
from django import forms
from rksite.models import Message
class EmailForm(forms.ModelForm):
name = forms.CharField(max_length=200,help_text="Name:")
email = forms.EmailField(help_text="Email:")
subject = forms.CharField(max_length=100, help_text="Subject:")
message = forms.CharField(max_length=1000, widget=forms.Textarea, help_text="Message:")
class Meta:
model = Message #link the model to the form
And finally, I'll also include the form's html page below:
{% extends 'rksite/base.html' %}
{% block title %}RaghavKumarContact{% endblock %}
{% block content %}
<h1>Contact Me</h1>
<br />
<form class="span6" id="email_form" method="POST" action="/home/contact/">
{% csrf_token %}
{% for field in form.visible_fields %}
{{ field.errors }}
{{ field.help_text }}
{{ field|linebreaks }}
{% endfor %}
<br />
<button class="btn btn-primary" type="submit" name="send">Send</button>
</form>
{% endblock %}
Now, no matter what I do, the "br/" tag shows up inside the "Message" Textarea field. Here's what I see on my webpage:
How can I get rid of this tag from this Textarea?
EDIT:
This is what it'll look like if I don't have the linebreaksfilter applied:
What is an alternative to the linebreaks filter??
Don't use linebreaks here:
{{ field|linebreaks }}
That renders the widget for the form, then passes the entire rendered HTML block through the linebreaks filter. That filter converts newlines into <br /> tags, and the rendering for a Textarea widget includes a newline before the text:
def render(self, name, value, attrs=None):
if value is None:
value = ''
final_attrs = self.build_attrs(attrs, name=name)
return format_html('<textarea{}>\r\n{}</textarea>',
flatatt(final_attrs),
force_text(value))
(Source from https://github.com/django/django/blob/master/django/forms/widgets.py#L435)
I'm not sure why you'd want to pass the field values though linebreaks - an HTML textarea should handle regular linebreaks in the message text just fine, if that's what you're worrying about.

How to access and make use of html data in django?

I am having a hard time figuring out the right logic for my problem, i have 3 models,
class Item(SmartModel):
name= models.CharField(max_length=64,help_text="Name for this item e.g Hamburger")
price=models.DecimalField(max_digits=9,decimal_places=2)
optionalitems = models.ManyToManyField('optionalitems.OptionalItemCategory',null=True,blank=True)
class OptionalItems(SmartModel):
"""Optional items that belong to an item e.g topping that belongs to a pizza"""
name = models.CharField(max_length=20, help_text="Item name.")
price = models.DecimalField(max_digits=9, decimal_places=2, null=True,blank=True)
class OptionalItemCategory(SmartModel):
"""Category to which optional items belong"""
title = models.CharField(max_length=20,help_text="Category name")
optional_items = models.ManyToManyField(OptionalItems)
in my template,
{%for optionalcategory in optionalcategories %}
<h5 id="blah"> {{ optionalcategory.title}} </h5>
{% for optionalitem in optionalcategory.optional_items.all %}
<ul>
<input type="radio" value="radio" name="optional" value="op"><li id="item_appearence">{{optionalitem.name}}<span> {{optionalitem.price}}</span></li><a/>
</ul>
{% endfor %}
{% endfor %}
So for example an Item like a burrito will have an OptionalItem steak or chicken.I am able to access the Item like so item = get_object_or_404(Item, pk=obj.id) but my problem is i cannot figure out how to capture the OptionalItem. I want to be able to access the OptionalItem, i want to obtain the value of the radio button and its attributes. its kind of tricky.
Your code is inconsistent and that makes it hard to read, understand and work with. Some advice, clean it up. Something like this:
class Category(models.Model):
name = models.CharField(max_length=200)
class Option(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
class Item(models.Model):
category = models.ForeignKey(Category)
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=9, decimal_places=2, blank=True, null=True)
options = models.ManyToManyField(Option)
Than you need a from and a view. As I interpret your question: you want a form to select a option for an Item. So the code below will render all options and the widget RadioSelect() lets the user select one item. But why use radiobuttons? If an Item has a relation to one Option, than the Item model should have a foreignKey not M2M!
Form:
class ItemForm(ModelForm):
options = forms.ChoiceField(widget=forms.RadioSelect())
class Meta:
model = Item
fields = ( 'options', )
View:
from django.shortcuts import render
from django.http import HttpResponseRedirect
def your_view(request, id):
item = Item.objects.get(pk=id) # Your item object.
if request.method == 'POST': # If the form has been submitted...
form = ContactForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
# Process the data in form.cleaned_data
options = form.cleaned_data['options']
# ...
return HttpResponseRedirect('/thanks/') # Redirect after POST
else:
form = ArticleForm(instance=article)
return render(request, 'contact.html', {
'form': form,
})
Template:
{% for obj in item.options_set.all %}
{{ obj.name }} {{ obj.price }}
{% endfor %}
<form action="" method="post">{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Submit" />
</form>
I dind't test the code. But this should get you started. The documentation is your friend:
https://docs.djangoproject.com/en/1.5/topics/forms/
https://docs.djangoproject.com/en/1.5/#forms
In your template, you can simply render the price. I'd write a method in the Item model, that formats the OptionalItems the way you like.
i.e.
class Item(SmartModel)
...
def get_optional(self):
return ','.join([a.optionalitems for a in self.optionalitems.all()])
Of course, you should change that method to have it format the way you'd like.
If you pass a queryset of Items to your template, you can do something like the following:
{% for item in items %}
Name: {{ item.name}}
Price: {{ item.price }}
Optional Items: {{ item.get_optional }}
{% endfor %}