How can i fetch a specific to a variable - python

Hello i want to fetch a specific field to a variable
For that I have Order model:
class Order(models.Model):
product = models.ForeignKey(
Product, on_delete=models.CASCADE, related_name="product")
customer = models.ForeignKey(Customer, on_delete=models.CASCADE)
quantity = models.IntegerField(default=1)
fname = models.CharField(max_length=100, null=True)
address = models.CharField(max_length=1000, null=True)
phone = models.CharField(max_length=12, null=True)
price = models.IntegerField()
date = models.DateField(datetime.datetime.today, null=True)
status = models.ForeignKey(
Status, on_delete=models.CASCADE, blank=True, null=True)
payment_method = models.ForeignKey(
PaymentMethod, on_delete=models.CASCADE, blank=True, null=True)
total = models.IntegerField(null=True)
Here I want to fetch total field in a variable.But I am new for that reason I am really confused about this topic

There is another method you can use. You would have to define a method or property for the field and then call it in your templates.
models.py
class Order(models.Model):
total = models.IntegerField(null=True)
#property
def get_total(self):
return self.total
views.py
from django.shortcuts import render
from .models import *
def Index(request):
Orders = Order.objects.all()
context = {"Orders":Orders}
return render(request, "template/page.html", context)
page.html
{% for order in Orders %}
{{order.get_total}}
# You can do the same to other field to get them
{% endfor %}

Its quite easy. Since you have defined your models already. All you have to do is to use it in your view.py and then in your templates. Exaple is the below:
view.py
from django.shortcuts import render
from .models import *
def Index(request):
Orders = Order.objects.all()
context = {"Orders":Orders}
return render(request, "template/page.html", context)
page.html
{% for order in Orders %}
{{order.total}}
{{order.price}}
# You can do the same to other field to get them
{% endfor %}

Related

User has no customer

In a Django project, i have two apps; ecommerce and users. Ecommerce app has situation where logged in users are expected to be customers and they can add to cart. Non logged in users can as well add to cart. In the users app, new users are to register, logged in and be redirected to the store page(store.html).
The new registered users does not have this customer instance I guess, reason I'm getting the User has no customer RelatedObjectDoesNotExist.
How can I integrate this new registered users to have this customer instance so they can be redirected to the store page? or give a condition where not all users must have a customer instance.
(ecommerce app)
models.py:
class Customer(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
name = models.CharField(max_length=200, null=True)
email = models.CharField(max_length=200)
def __str__(self):
"""String for representing a model object"""
return self.name
class Product(models.Model):
name = models.CharField(max_length=200)
price = models.DecimalField(max_digits=7, decimal_places=2)
digital = models.BooleanField(default=False,null=True, blank=True)
image = models.ImageField(null=True, blank=True)
def __str__(self):
"""String for representing a model object"""
return self.name
#property
def imageURL(self):
try:
url = self.image.url
except:
url = ''
return url
class Order(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True, blank=True)
date_ordered = models.DateTimeField(auto_now_add=True)
complete = models.BooleanField(default=False, null=True, blank=True)
transaction_id = models.CharField(max_length=100, null=True)
def __str__(self):
"""String for representing a model object"""
return str(self.id)
#property
def shipping(self):
shipping = False
orderitems = self.orderitem_set.all()
for i in orderitems:
if i.product.digital == False:
shipping = True
return shipping
#property
def get_cart_total(self):
orderitems = self.orderitem_set.all()
total = sum([item.get_total for item in orderitems])
return total
#property
def get_cart_items(self):
orderitems = self.orderitem_set.all()
total = sum([item.quantity for item in orderitems])
return total
class OrderItem(models.Model):
product = models.ForeignKey(Product, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
quantity = models.IntegerField(default=0, null=True, blank=True)
date_added = models.DateTimeField(auto_now_add=True)
#property
def get_total(self):
total = self.product.price * self.quantity
return total
class ShippingAddress(models.Model):
customer = models.ForeignKey(Customer, on_delete=models.SET_NULL, null=True)
order = models.ForeignKey(Order, on_delete=models.SET_NULL, null=True)
address = models.CharField(max_length=200, null=False)
city = models.CharField(max_length=200, null=False)
state = models.CharField(max_length=200, null=False)
zipcode = models.CharField(max_length=200, null=False)
date_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
"""String for representing a model object"""
return self.address
utils.py
(it is being imported to views.py and then rendered to the store.html template):
def cartData(request):
if request.user.is_authenticated:
customer = request.user.customer
order, created = Order.objects.get_or_create(customer=customer, complete=False)
items = order.orderitem_set.all()
cartItems = order.get_cart_items
else:
cookieData = cookieCart(request)
cartItems = cookieData['cartItems']
order = cookieData['order']
items = cookieData['items']
return {'cartItems':cartItems ,'order':order, 'items':items}
views.py
def store(request):
data = cartData(request)
cartItems = data["cartItems"]
products = Product.objects.all()
#context = {'products': products }
context = { "products": products,'cartItems':cartItems}
return render(request, 'ecommerce/store.html', context)
This the main.html snippet template where both apps(ecommerce app and users app) inherits from.
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="{% url 'store' %}">Ecommerce<span class="sr-only">(current)</span></a>
</li>
</ul>
<div class="form-inline my-2 my-lg-0">
{% if request.user.is_authenticated %}
Logout
{% else %}
Login
Register
{% endif %}
(users app) below:
it has no models.py
forms.py
from django import forms
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class UserRegistrationForm(UserCreationForm):
email = forms.EmailField()
class Meta:
model = User
fields = ['username', 'email', 'password1', 'password2']
views.py
from django.shortcuts import render, redirect
#from django.contrib.auth.forms import UserCreationForm
from django.contrib import messages
from .forms import UserRegistrationForm
def register(request):
if request.method == "POST":
form = UserRegistrationForm(request.POST)
if form.is_valid():
form.save()
username = form.cleaned_data.get('username')
messages.success(request, f'{username}, your account has been created! You are able to log in')
return redirect('login')
else:
form = UserRegistrationForm()
return render(request, 'users/register.html', {'form':form})
settings.py
LOGIN_REDIRECT_URL = 'store' #redirecting to store page after a successful login session configuration.
Yo must create the Customer with the User you are trying to access the store.

how to split post view on the same page in django

I have no idea if this question make much sense or not but i am so confused about it. I have a post list view and it is rendering some of the post here.
My question is how can I split the sections of the page.something like this.
what should be the approach of making this kind of view.
this is my posts view.py
posts/view.py
class PostListView(ListView):
model = Post
template_name = 'posts/home.html'
context_object_name = 'posts'
ordering = ['-date_posted']
def get_queryset(self):
if not self.request.user.is_authenticated:
return Post.objects.all()[:10]
else :
return super().get_queryset()
posts/models.py
from django.db import models
from django.utils import timezone
from slugger import AutoSlugField
from django.contrib.auth.models import User
from django.urls import reverse
# Create your models here.
def upload_location(instance, filename):
return "%s/%s" %(instance.slug, filename)
class Category(models.Model):
title = models.CharField(max_length= 60)
slug = AutoSlugField(populate_from='title')
parent = models.ForeignKey('self',blank=True, null=True ,related_name='children',on_delete=models.CASCADE)
updated = models.DateTimeField(auto_now=True, auto_now_add=False)
timestamp = models.DateTimeField(auto_now=False, auto_now_add=True)
def __unicode__(self):
return self.title
def __str__(self):
return self.title
class Post(models.Model):
title = models.CharField(max_length=120)
slug = AutoSlugField(populate_from='title')
image = models.ImageField(
upload_to=upload_location,
null=True,
blank=True,
)
category = models.ForeignKey(Category, on_delete=models.CASCADE)
content = models.TextField()
date_posted = models.DateTimeField(default=timezone.now)
author = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.title
def get_absolute_url(self, slug=None):
return reverse("posts-detail", kwargs={"slug": self.slug})
You have posts assigned to categories. Each post could be assigned only to one category (since you have FK from Post to Category). And you want to display all categories and 10 latest posts under each one.
I see several ways of how to solve that. The easiest one is to extend Category model with property, containing the queryset to retrieve related posts in the way you want them for front page.
class Post(models.Model):
title = models.CharField(max_length=255)
category = models.ForeignKey('Category', on_delete=models.CASCADE, related_name='posts')
date_posted = models.DateTimeField(default=timezone.now)
class Category(models.Model):
title = models.CharField(max_length=255)
#property
def posts_for_frontpage(self):
return self.posts.order_by('-date_posted')[:10]
class FrontpageView(ListView):
model = Category
template_name = 'frontpage.html'
context_object_name = 'categories'
def get_queryset(self):
# select some categories for frontpage
# all by default
return Category.objects.all()
and then in template
{% for category in categories %}
<h1>{{ category.title }}</h1>
<hr />
{% for post in category.posts_for_frontpage %}
<h4>{{ post.title }}</h4>
{% endfor %}
<br />
<br />
{% endfor %}
You could also play with select_related to reduce number of queries and with annotate to get all related posts.

Need to know the way to access to my Reply table?

Here is my models.py py file.
from django.db import models
from django.conf import settings
from django.urls import reverse
class Article(models.Model):
'''Modelling the article section.'''
title = models.CharField(max_length=200)
body = models.TextField()
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
date = models.DateTimeField(auto_now_add=True)
def __str__(self):
'''Return string representation of the model.'''
return self.title
def get_absolute_url(self):
'''Return the url of this model.'''
return reverse('article_detail', args=[str(self.id)])
class Comment(models.Model):
'''Modelling the comment section.'''
article = models.ForeignKey(
Article,
on_delete = models.CASCADE,
related_name = 'comments'
)
comment = models.CharField(max_length=150)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE)
def __str__(self):
'''String representation of the model. '''
return self.comment
class Reply(models.Model):
''' Modelling the reply section. '''
comment = models.ForeignKey(
Comment,
on_delete = models.CASCADE,
related_name = 'replys'
)
reply = models.CharField(max_length=100)
author = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
def __str__(self):
''' String representation of the model. '''
return self.reply
I need to access my Reply table in the Detail View template(Using generic view class DetailView). I have tried so far the following command in the template.
article.comments.replys.all
Its not able to retrive any data from Reply table. Thanks in advance.
article.comments is a manager; you need to iterate over it to get Comment instances. Each one will have .replys.
{% for comment in article.comments.all %}
{% for reply in comment.replys.all %}
...
{% endfor %}
{% endfor %}

Template filter for generating product by category

I have a django project where I am displaying products in the template. What is the best possible way of displaying the product by category using some sort of template filter. For instance, on the template if I want to display Breads by category Hovis. At the moment all the products in the database will be displayed.
<tr>
<td><h5>{{ product.name }}</h5></td>
<td><p><strong>{{ product.price }}</strong></p></td>
</tr>
Copy of Models.py (as requested):
from django.db import models
from django.core.urlresolvers import reverse
class Category(models.Model):
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True, unique=True)
class Meta:
ordering = ('name',)
verbose_name = 'category'
verbose_name_plural = 'categories'
def __str__(self):
return self.name
# def get_absolute_url(self):
# return reverse('shop:product_list_by_category', args=[self.slug])
class Product(models.Model):
category = models.ForeignKey(Category, related_name='products')
name = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(max_length=200, db_index=True)
description = models.TextField(blank=True)
price = models.DecimalField(max_digits=10, decimal_places=2)
available = models.BooleanField(default=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
class Meta:
ordering = ('-created',)
index_together = (('id', 'slug'),)
def __str__(self):
return self.name
# def get_absolute_url(self):
I would send the already prepared data from the view to the template to avoid additional logic in the front-end. You could do something like this in the view:
products = Product.objects.all()
all_products_by_cat ={}
for product in products:
if all_products_by_cat.get(product.category):
all_products_by_cat[product.category].append(product)
else:
all_products_by_cat[product.category] = [product]
And in the template you would just do:
{% for product in all_products_by_cat['some_category'] %}
<!-- do something with the product-->
{% endfor %}

For loop counter in Django, numbers not showing up

I'm looking to have a counter of numbers from one to ten using a for loop counter in Django, but I don't see any numbers. I don't really understand what I need to put in {{counter}} and {{value}} when looking at the documentation.
List.html
<p class="number">
{% for key, value in data.items %}
{{counter}}: {{value}}
{% endfor %}
<p>
models.py
from django.db import models
from django.core.urlresolvers import reverse
# Create your models here.
class FullArticleQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
class FullArticle(models.Model):
title = models.CharField(max_length=150)
author = models.CharField(max_length=150)
slug = models.SlugField(max_length=200, unique=True)
pubDate = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
category = models.CharField(max_length=150)
heroImage = models.CharField(max_length=250, blank=True)
relatedImage = models.CharField(max_length=250, blank=True)
body = models.TextField()
publish = models.BooleanField(default=True)
gameRank = models.CharField(max_length=150, blank=True, null=True)
objects = FullArticleQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("FullArticle_detailed", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog entry"
verbose_name_plural = "Blog Entries"
ordering = ["-pubDate"]
views.py
from django.views import generic
from . import models
from .models import FullArticle
# Create your views here.
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
randomArticle = FullArticle.objects.order_by('?').first()
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
use {{ forloop.counter }} instead of just {{ counter }}
Also, you are never defining the dictionary data anywhere. What is this supposed to be? Your queryset?

Categories

Resources