I have two models
class AccGroup(models.Model):
grpid = models.BigAutoField(primary_key=True, editable=False)
groupname = models.CharField(max_length=40, default="")
class Meta:
indexes = [models.Index(fields=['groupname'])]
def __str__(self):
return "%s" % (self.groupname)
class Account(models.Model):
accid = models.BigAutoField(primary_key=True, editable=False)
shortcut = models.CharField(max_length=10, default="")
accname = models.CharField(max_length=100, default="")
accgrp = models.ForeignKey(AccGroup, on_delete=models.RESTRICT, default=0)
class Meta:
indexes = [models.Index(fields=['shortcut']),models.Index(fields=['accname'])
]
def __str__(self):
return "%s--%s" % (self.shortcut, self.accname)
One Update View defined on above model
class AccountUpdateForm(UpdateView):
model = Account
fields = ['shortcut','accname','accgrp']
def get_success_url(self):
currid = self.kwargs['pk']
account = Account.objects.get(pk=currid)
print(account)
return ('/polls/accmst/'+ str(account.accid))
and the corresponding HTML templet
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Update Account</title>
</head>
<body>
<form action="" method="post">
{% csrf_token %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="Save" />
</form>
<p>
<a class="btn btn-info btn-sm" href="{% url 'polls:accgrpList' %}">Back To Group List</a>
</p>
<p>
<a class="btn btn-info btn-sm" href="{% url 'polls:accgrpList' form.accgrp.grpid %}">Back To Account List</a>
</p>
</body>
</html>
so on success the same page is displayed using the current account object primary key
there are two more links
Link 1 point the a group list <polls:accgrpList> which translates to http://localhost:8000/polls/accgrplist
Link 2 my problem is I want to point to url
http://localhost:8000/polls/accgrplist/2
where the last part is the grpid of the current account object
following change in my templet did my job
<a class="btn btn-info btn-sm" href="{% url 'polls:accgrpList' form.accgrp.value %}">Back To Account List</a>
Related
I have built a photo gallery and I when an image is opened I would like to add to buttons ( Previous & Next) Which will cycle through my images based on their id/pk.
Models.py
class PostImage(models.Model):
image = models.ImageField(null=False, blank=False, upload_to="images", default="default.png")
image_title = models.CharField(max_length=100, null=False, blank=False, default="")
def __str__(self):
return self.image_title
class Meta:
verbose_name_plural = 'PostImage'
Views.py
def galleryPage(request):
images = PostImage.objects.all()
context = {'images':images}
return render(request, 'gallery.html', context)
def viewImage(request, pk):
photo = PostImage.objects.get(id=pk)
return render(request, 'viewimage.html', {'photo': photo})
HTML
<div class="image-container">
<div class="image-post">
<a href="{% url 'gallery' %}"
><img class="photo-img" src="{{photo.image.url}}"
/></a>
<h2 class="photo-title">{{photo.image_title}}</h2>
<p class="contact">
Interested in purchasing this as a print? Contact me for more
information regarding price and sizes.
</p>
<a href="{% url 'contact' %}" class="btn btn-secondary" type="button"
>Contact</a
>
</div>
</div>
</body>
</html>
I'm trying to add search bar in my application but I don't know how to query a database to gives the things that user's search for. I want when user search for a user in a post or category in a post of model to shows the result that user search for, like YouTube search and facebook search, How can i do this in django to give me what i want ?
this is my model:
class Photo(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
category = models.CharField(max_length=30,null=True, blank=False)
image = CloudinaryField(blank=False, null=False)
description = models.TextField(null=True)
date_added = models.DateTimeField(auto_now_add=True)
phone = models.CharField(max_length=12, null=False, blank=False)
price = models.CharField(max_length=30,blank=False)
location = models.CharField(max_length=20, blank=False)
def __str__(self):
return str(self.category)
my search form in dashboard template:
<div class="container">
<div class="row justify-content-center">
<form action="{% url 'search' %}" method="get">
<input class="form-control me-2" type="search" placeholder="Search" aria-
label="Search">
<br>
<button class="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</div>
the post card in dashboard template:
<div class="container">
<div class="row justify-content-center">
{% for photo in photos reversed %}
<div class="col-md-4">
<div class="card my-2">
<img class="image-thumbail" src="{{photo.image.url}}" alt="Card image cap">
<div class="card-body">
<h2 style="color: yellowgreen; font-family: Arial, Helvetica, sans-serif;">
{{photo.user.username.upper}}
</h2>
<br>
<h3>{{photo.category}}</h3>
<h4>{{photo.price}}</h4>
</div>
<a href="{% url 'Photo-view' photo.id %}" class="btn btn-warning
btn-sm m-1">Buy Now</a>
</div>
</div>
{% empty %}
<h3>No Files...</h3>
{% endfor %}
</div>
</div>
the dashboard view:
def dashboard(request):
photos = Photo.objects.all()
context = {'photos': photos}
return render(request, 'dashboard.html', {'photos': photos} )
the search bar view:
def search(request):
return render(request, 'search.html')
urls:
path('', views.dashboard, name='dashboard'),
path('search/', views.search, name='search')
You can make it using filter method inside your view. Something like:
def dashboard(request):
photos_filter = request.GET.get('filtered[]', False)
photos = Photo.objects.all()
if photos_filter:
photos_filter = eval(photos_filter)
if photos_filter['id'] == 'category':
payments = payments.filter(
category__icontains=payments_filter['value'])
if photos_filter['id'] == 'user':
payments = payments.filter(
user__id=payments_filter['value'])
context = {'photos': photos}
return render(request, 'dashboard.html', {'photos': photos} )
And so on, you can add any filter you like. And in your URL you just add
/?filtered[]=%7B%22id%22:%22category%22,%22value%22:%22Nature%22%7D
Your code will see this filter like a dict obj: {'id': 'category', 'value': 'Nature'}. So after it, you'll get all photos with the category nature
I am having a challenge displaying multiple images users post to one img template element, for one reason if i try fetching images with the default related name it wouldn't show in the template and i wonder what i am doing wrong. Can anyone be of help!
Here is my model for post.
class Post(models.Model):
page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="page")
username = models.ForeignKey(settings.AUTH_USER_MODEL,on_delete=models.CASCADE ,related_name="page_user")
description = models.TextField(max_length=500, blank=True)
video = models.FileField(upload_to="PageVideos", blank=True)
pic = models.ImageField(blank=True)
date_posted = models.DateTimeField(auto_now_add=True)
tags = models.CharField(max_length=100, blank=True)
class Mete:
ordering = ['-date_posted']
def __str__(self):
return self.description
class PostImage(models.Model):
#page = models.ForeignKey(Page, on_delete=models.CASCADE, related_name="pg")
post = models.ForeignKey(Post, default=None, on_delete=models.CASCADE)
images= models.ImageField(upload_to="postimages/")
Here is my Detail view
def page_detail(request,id):
post = get_object_or_404(Post, id=id)
photos = PostImage.objects.filter(post=post)
context = {
'post':post,
'photos':photos
}
return render(request, 'page/detail.html',context)
These my Template to display users images
<div class="p-3 border-b dark:border-gray-700">
{{ post.description }}
</div>
<div uk-lightbox>
<div class="grid grid-cols-2 gap-2 p-2">
{% for p in photos.images_set.all %}
<a id="images" href="{{ p.images.url }}" class="col-span-2" >
<img src="{{ p.images.url }}" alt="" class="rounded-md w-full lg:h-76 object-cover">
</a>
<a href="">
<img src="" alt="" class="rounded-md w-full h-full">
</a>
<a href="" class="relative">
<img src="" alt="" class="rounded-md w-full h-full">
<div class="absolute bg-gray-900 bg-opacity-30 flex justify-center items-center text-white rounded-md inset-0 text-2xl"> + see more </div>
</a>
{% endfor %}
</div>
</div>
your photos is a list you dont need reverse m2m (the "images_set") simply change this in html
....
<div class="grid grid-cols-2 gap-2 p-2">
{% for p in photos %}
....
for optimize you can do this
from django.http import Http404
...
def page_detail(request,id):
try:
# with prefetch you do only one sql request
post = Post.objects.select_related('images_set').get(id=id)
expect Post.DoesNotExist as err:
raise Http404(err)
context = {
'post': post,
'photos': post.images_set.all()
}
return render(request, 'page/detail.html',context)
Scratching my head trying to figure out what I'm doing wrong. I am trying to retrieve data from an input field on my website and insert it into a sql table. When i click the submit button on my website I keep getting this error NOT NULL constraint failed:auctions_bid.listing_id_id
What is causing this? any help is very much appreciated. Thanks I've attached my models.py, views.py and html pages below for additional context.
Models.py
class User(AbstractUser):
pass
class Category(models.Model):
category_id = models.AutoField(primary_key=True)
category_name = models.CharField(max_length=100)
def __str__(self):
return f"{self.category_name}"
class Auction_listing(models.Model):
listing = models.AutoField(primary_key=True)
user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="listings")
start_price = models.IntegerField()
product_name = models.CharField(max_length=50)
prod_description = models.CharField(max_length=350)
category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name="bids")
list_img = models.ImageField(null=True, blank=True)
def __str__(self):
return f"{self.user_id}: {self.product_name} ${self.start_price}"
class Bid(models.Model):
bid = models.IntegerField()
user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_bids")
listing_id = models.ForeignKey(Auction_listing, on_delete=models.CASCADE, related_name="all_bids")
class Comments(models.Model):
comment = models.CharField(max_length=500)
user_id = models.ForeignKey(User, on_delete=models.CASCADE, related_name="user_comments")
listing_id = models.ForeignKey(Auction_listing, on_delete=models.CASCADE, related_name="all_comments")
views.py
def listing(request, listing):
#Find user id
current_user = request.user
new_bid = ''
bid_count = Bid.objects.filter(listing_id=listing).count()
#Gets the max bid for a particular listing in dictionary form
max_bid = Bid.objects.filter(listing_id=listing).aggregate(Max('bid'))
#Gets value of the bid__max key
max = max_bid['bid__max']
#Get all objects for particular listing
page_listing = Auction_listing.objects.get(pk=listing)
if request.method == "POST":
bid = int(request.POST.get('Bid'))
if bid > int(max):
**new_bid = Bid(bid, current_user.id, listing)**
**new_bid.save()**
return HttpResponseRedirect(reverse("listing"))
#return render(request, "auctions/listing.html", {
#"page_listing": page_listing,
#"Bid": bid_count,
#"Max": max,
#"Message": "Your bid has been reflected below"
#})
else:
return render(request, "auctions/listing.html", {
"page_listing": page_listing,
"Bid": bid_count,
"Max": max,
"Message":'Value entered must be larger than current Bid'
})
else:
return render(request, "auctions/listing.html", {
"page_listing": page_listing,
"Bid": bid_count,
"Max": max,
"User": current_user
})
HTML Template
{% extends "auctions/layout.html" %}
{% block body %}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
{{ number }}
{{ Max }}
{{ User }}
<div class="">
<h1>Listing:{{page_listing.product_name}}</h1>
</div>
<div class="">
<img src="{{page_listing.list_img.url}}" alt="">
</div>
<div class="">
<h3>{{ page_listing.prod_description }}</h3>
</div>
<div class="">
<h3>{{ Bid }} bid(s) so far for this item</h3>
{{ page_listing.start_price }}
</div>
<form class="" action="/listing/{{ page_listing.listing }}" method="post">
{% csrf_token %}
<div class="">
<input type="text" name="Bid" value="Place bid">
</div>
<div class="">
<input type="submit" name="submit" value="Place Bid">
</div>
</form>
</body>
</html>
{% endblock %}
This view is supposed to find a blog post and change it's information, but instead of that it just makes a new Blog object with the new (and old) information.
The update view
#login_required
def view_updatepost(request, blog_id):
if not request.user.is_staff or not request.user.is_superuser:
raise Http404
#post = Blog.objects.get(pk=blog_id)
post_to_be_changed = get_object_or_404(Blog, pk=blog_id)
form = BlogForm(request.POST or None, instance=post_to_be_changed)
if form.is_valid():
post_to_be_changed = form.save(commit=False)
#
#
post_to_be_changed.save()
#messages.success(request, "<a href='#'>Item</a> Saved", extra_tags='html_safe')
return HttpResponseRedirect(post_to_be_changed.get_absolute_url())
context = {
'post_to_be_changed': post_to_be_changed,
'form': form,
}
return render(request, 'blog/makepost.html', context)
The template used by the view makepost.html
{% extends "base.html" %}
{% load staticfiles %}
{% block main_content %}
<!-- Page Header -->
<!-- Set your background image for this header on the line below. -->
<header class="intro-header" style="background-image: url('{% static "img/about-bg.jpg" %}')">
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
<div class="page-heading">
<h1>Make a Post</h1>
<hr class="small">
<span class="subheading">Share with the World.</span>
</div>
</div>
</div>
</div>
</header>
<!-- Main Content -->
<div class="container">
<div class="row">
<div class="col-lg-8 col-lg-offset-2 col-md-10 col-md-offset-1">
{% if not user.is_authenticated %}
You must be <u>logged in</u> to make a post.
{% else %}
<form action="{% url "makepost" %}" method="post">
{% csrf_token %}
{{form.as_p}}
<div align="center">
<input class="btn btn-default" type="submit" value="Post to Blog" onclick="window.location='{% url "" %}';"/>
{# Home #}
</div>
</form>
{% endif %}
</div>
</div>
</div>
<hr>
{% endblock main_content %}
The models.py
from django.db import models
import datetime
# Create your models here.
class Blog(models.Model):
title = models.CharField(max_length=250)
subtitle = models.CharField(max_length=250, null = True, blank=True)
date_added = models.DateTimeField(default=datetime.datetime.now())
image = models.TextField(max_length=1000, null = True, blank=True)
tags = models.TextField(max_length=500, null=True, blank=True)
article = models.TextField(max_length=15000, null=True, blank=True)
author = models.CharField(max_length=150, null=True, blank=True)
def get_absolute_url(self):
return "/blog/%i" % self.pk
The forms.py
from django import forms
from .models import Blog
import datetime
class PostForm(forms.Form):
title = forms.CharField()
subtitle = forms.CharField(required=False)
date_added = forms.DateTimeField()
image = forms.URLField(required=False)
tags = forms.CharField(required=False)
article = forms.CharField()
author = forms.CharField()
class BlogForm(forms.ModelForm):
class Meta:
model = Blog
fields = ('title', 'subtitle',
'image', 'tags', 'article')
It seems that you are not referring to your update view in your form action url:
<form action="{% url **"makepost"** %}" method="post">