I'm trying to create a Streamfield block that basically displays all of the posts (diagnoses) from a standard diagnoses listing page so that not only do I have a separate diagnoses page but am also able to add a diagnoses/posts block to other pages?
I've got this so far but it's not working:
Streams > blocks.py:
class DiagnosesListingBlock(blocks.StructBlock):
title = blocks.CharBlock(
required= True,
defualt="Diagnoses",
help_text = 'Text to display as title of Diagnoses section.'
)
data_items = blocks.IntegerBlock(
max_length=2,
blank=False,
null=False,
default="3",
)
def get_context(self, request, *args, **kwargs):
context = super().get_context(request, *args, **kwargs)
context['diagnoses'] = diagnoses.DiagnosisPage.objects.live().public()
return context
class Meta:
template = "streams/disgnoses_listing_block.html"
icon = "edit"
label = "Diagnoses Listing Block"
help_text = "Centered text to display on a page"
Diagnoses > model.py:
class DiagnosisPage(Page):
template = "diagnoses/diagnosis_page.html"
diagnosis_name = models.TextField(
blank=True,
max_length=100,
)
subtitle = models.TextField(
blank=True,
max_length=500,
)
diagnosis_intro = models.TextField(
blank=True,
max_length=500
)
image = models.ForeignKey(
'wagtailimages.Image',
blank=False,
null=True,
on_delete=models.SET_NULL,
help_text='This image will be used on the service listing page and will be cropped to 570px by 370px.',
related_name='+',
)
summary = models.CharField(
max_length=160,
blank=False,
null=False,
default='Curabitur pulvinar euismod ante, ac sagittis ante posuere ac. Vivamus luctus commodo dolor porta feugiat. Fusce at velit id ligula pharetra laoreet.',
help_text='Provides an excert for the blog listing page that gives an intro to what the article is about.',
)
body = StreamField([
("hero_block", blocks.HeroBlock()),
("breadcrumb_block", blocks.BreadcrumbsBlock()),
("highlighted_text_block", blocks.HighlightedTextBlock()),
("title", blocks.TitleAndTextBlock()),
("about_us", blocks.AboutBlock()),
("cards", blocks.CardsBlock()),
("icon_boxes_one", blocks.TextBoxesOneBlock()),
("links", blocks.SiteLinksBlock()),
("image_and_text", blocks.ImageAndTextBlock()),
("image_right_and_text", blocks.ImageRightAndTextBlock()),
("team_members", blocks.TeamMembersBlock()),
("cta_1", blocks.CallToActionOneBlock()),
("cta_2", blocks.CallToActionTwoBlock()),
("cta_3", blocks.CallToActionThreeBlock()),
("large_modal_block", blocks.LargeModalBlock()),
("counters_block", blocks.CountersBlock()),
("share_this_post", blocks.ShareThisPostBlock()),
("blockquotes", blocks.BlockquoteBlock()),
("accordions", blocks.AccordionBlock()),
("testimonial", SnippetChooserBlock(
target_model='testimonials.Testimonial')),
("our_numbers", blocks.OurNumbersBlock()),
("progress_bars", blocks.ProgresssBarsBlock()),
("testimonial", SnippetChooserBlock(
target_model='testimonials.Testimonial',
template='streams/testimonial_block.html'
)),
("pricing_table", blocks.PricingTableBlock(
table_options=new_table_options)),
("logo_block", blocks.LogoBlock()),
("timeline_block", blocks.TimelineBlock()),
("richtext", blocks.RichTextWithTitleBlock()),
], blank=True, null=True)
content_panels = Page.content_panels + [
FieldPanel('diagnosis_name'),
FieldPanel('subtitle'),
FieldPanel('diagnosis_intro'),
ImageChooserPanel('image'),
StreamFieldPanel("body"),
]
diagnosis_listing_block.html:
{% load wagtailcore_tags wagtailimages_tags %}
<section class="p-t-100 p-b-100">
<div class="container">
<div class="row" style="display: table;width: 100%;">
<div class="col-lg-12">{{ self }}
<!--Post Carousel -->
<h4 class="mb-4">{{ self.title }}</h4>
<div class="carousel" data-items="{{ self.data_items }}">
{% for diagnosis in self.diagnoses %}
<!-- Post item-->
<div class="post-item border" style="display: table-cell;">
<div class="post-item-wrap">
<div class="post-image">
<a href="{{ diagnosis.url }}">
{% image diagnosis.image fill-250x150 format-webp as diagnosis_img %}
<img alt="{{ diagnosis.diagnosis_name }} | Dual Diagnosis Network Blog" src="{{ diagnosis_img.url }}"></a>
<!--<span class="post-meta-category"></span>-->
</div>
<div class="post-item-description">
<span class="post-meta-date"><i class="fa fa-calendar-o"></i>Jan 21, 2017</span>
<span class="post-meta-comments"><a href="{{ diagnosis.url }}"><i class="fa fa-comments-o"></i>33
Comments</a></span>
<h2>{{ diagnosis.diagnosis_name }}</h2>
<p>{{ diagnosis.summary }}</p>
Read More <i class="icon-chevron-right"></i>
</div>
</div>
</div>
{% endfor %}
<!-- end: Post item-->
</div>
<!--end: Post Carousel -->
</div>
</div>
</div>
</section>
{% for diagnosis in self.diagnoses %} should be {% for diagnosis in diagnoses %}.
The get_context method defines new variables to be available in the template - in this case, the context['diagnoses'] = ... line defines a variable diagnoses, and that's how you refer to it in the template. self.diagnoses would mean an attribute of the block value instead, but that doesn't exist - it only has attributes title and data_items.
Related
I'm about to finish a Django based project, and the last step of this project is to build a followers/following feature. I can unfollow someone I've followed manually from the admin, but I can't follow someone from my html view. It misses me just one tiny thing to add into my html code but I'm really stuck. My code
My Model:
from django.db import models
from django.contrib.auth.models import AbstractUser
# Create your models here.
class User(AbstractUser):
CREATOR = "CREATOR"
SUBSCRIBER = "SUBSCRIBER"
ROLE_CHOICES = (
(CREATOR, "Créateur"),
(SUBSCRIBER, "Abonné"),
)
profile_photo = models.ImageField(upload_to='profile_photos/', default='profile_photos/default.png', blank=True, null=True)
role = models.CharField(max_length=10, choices=ROLE_CHOICES, default=SUBSCRIBER)
follows = models.ManyToManyField('self', related_name='followers', symmetrical=False)
My Views:
#login_required
def abonnements(request):
user = request.user
followers = user.followers.all()
follows = user.follows.all()
if request.method == 'POST':
if request.POST.get('follow'):
if request.POST.get('follow') == user.username:
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows, "error": "You can't follow yourself!"})
try:
followed_user = User.objects.get(request.POST.get('follow'))
except User.DoesNotExist:
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows, "error": "User does not exist"})
else:
print(followed_user)
elif request.POST.get('unfollow'):
user.follows.remove(User.objects.get(pk=request.POST.get('unfollow')))
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows, "success": "You are no longer following " + request.POST.get('unfollow')})
return render(request, 'blog/abonnements.html', {'followers': followers, 'follows': follows})
My HTML
{% extends 'base.html' %}
<title>{% block title %}Abonnements{% endblock %}</title>
{% block content %} {% include 'partials/_navbar.html' %}
<main class="corps_abonnements">
<section class="suivre">
<p class="suivre_utilisateurs_titre">Suivre d'autres utilisateurs</p>
<form method="post">
{% csrf_token %}
<input type="text" name="follow" value="">
<input type="submit" value="Envoyer">
</form>
</section>
<section class="abonnements">
<p color="red">{{ error }}</p>
{% if success %}<p color="green">{{ success }}</p>{% endif %}
<p class="abonnements_titre">Abonnements</p>
{% for user in follows %}
<div class="utilisateur_desabonner_container">
<p class="nom_utilisateur_desabonner">{{ user.username }}</p>
<form method="post">
{% csrf_token %}
{% if user in follows %}
<input type="hidden" name="unfollow" value="{{ user.id }}">
<button style="background-color:red;" type="submit" class="creer_critique_demande">
Se désabonner
</button>
{% endif %}
</form>
</div>
{% endfor %}
</section>
<section class="abonnes">
<p class="abonnes_titre">Abonnés</p>
{% for user in followers %}
<div class="utilisateur_abonne_container">
<p class="nom_utilisateur_abonne">{{ user.username }}</p>
</div>
{% endfor %}
</section>
</main>
{% endblock %}
So when I put the connected user name in the input, it returns me the error "you can't follow yourself", it means that my code is good
the message
but If I try to put the username of another user I want to follow, it raises me an error. Can someone help me please ?
ValueError at /abonnements/
too many values to unpack (expected 2)
Request Method: POST
Request URL: http://127.0.0.1:8000/abonnements/
views.py, line 155, in abonnements
followed_user = User.objects.get(request.POST.get('follow'))
i am trying to update content with form but in my html is does not load up whenn i click on the link any idea what causing the error
my views.py
def edit_address(request, id):
address = Address.objects.filter(id=id)
form = Addressform(request.POST)
if form.is_valid():
form.user = request.user
form.save()
else:
form = Addressform()
template_name = "address_edit.html"
context = {
"form": Addressform,
"Address":Address.objects.get(id=id),
}
return render(request,template_name,context)
i think the issue is in views.py that's why i only add this file tell me if you want to see any else file
my html
<div class="card col-10">
<div class="form-group form-control-sm">
<h1 class="text-center">Edit Address</h1>
<a class='back' style="float: right;" href="{% url 'accounts:home' %}">Back to site</a> <br>
{% for Address in address %}
<form method="POST">
{% csrf_token %}
<div class="col-5">{{ form.reciever_name|as_crispy_field }}</div>
<div class="col-5">{{ form.phone_no|as_crispy_field }}</div>
<div class="col-5">{{ form.alt_phone_no|as_crispy_field }}</div>
<div class="col-5">{{ form.state|as_crispy_field }}</div>
<div class="col-5">{{ form.city|as_crispy_field }}</div>
<div class="col-5">{{ form.pincode|as_crispy_field }}</div>
<div class="col-5">{{ form.address|as_crispy_field }}</div>
<div class="col-5">{{ form.locality|as_crispy_field }}</div>
<div class="col-5">{{ form.eighteen|as_crispy_field }}</div>
<br>
<button type="submit" class="btn btn-outline-success">Add Address</button>
</form>
{% endfor %}
</div>
You need to obtain the instance of the address to edit, and pass it as instance=… to the AddressForm:
from django.shortcuts import get_object_or_404, redirect
def edit_address(request, id):
address = get_object_or_404(Address, id=id)
if request.method == 'POST':
form = Addressform(request.POST, instance=address)
if form.is_valid():
form.instance.user = request.user
form.save()
return redirect('name-of-some-view')
else:
form = AddressForm(instance=address)
template_name = 'address_edit.html'
context = {
'form': form,
'Address': address,
}
return render(request, template_name, context)
Note: In case of a successful POST request, you should make a redirect
[Django-doc]
to implement the Post/Redirect/Get pattern [wiki].
This avoids that you make the same POST request when the user refreshes the
browser.
Note: It might be better to use the #login_required decorator
[Django-doc]
as a decorator, and thus wrap the function in it like:
from django.contrib.auth.decorators import login_required
#login_required
def edit_address(request, id):
# …
Note: You should not create a new form in case the form was not valid. A form
that is not valid will store the problems with the input in the
form.errors dictionary, and if you render the form (automatically),
it will show the errors next to the fields where these errors occur.
I have two model Item and Women
this is the code for my 2 models
class Item(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField()
def __str__(self):
return self.title
class Women(models.Model):
title = models.CharField(max_length=100)
price = models.FloatField()
discount_price = models.FloatField(blank=True, null=True)
category = models.CharField(choices=CATEGORY_CHOICES, max_length=2)
label = models.CharField(choices=LABEL_CHOICES, max_length=1)
slug = models.SlugField()
description = models.TextField()
image = models.ImageField()
def __str__(self):
return self.title
In my view.py
I have created Homeview(View) to render the homepage.html which I have used get_context_data to render the two model which is the Item and Women.
this is code for my views.py
class HomeView(ListView):
template_name='Ecommerce/home-page.html'
def get_queryset(self):
return Item.objects.all()
def get_context_data(self, **kwargs):
et =super(HomeView, self).get_context_data(**kwargs)
et['Item_qs']= Item.objects.all()
et['women_qs']= Women.objects.all()
return et
class ProductDetailView(DetailView):
model= Women,Item
template_name='Ecommerce/product-page.html'
i dont know if i am writing the ProductDetailView correctly for the 2 models
Now within the homepage my first div I used the Item model to loop through
And my second div I used the Women model to loop through
this is how i rendered the two views in my html templates
the first one is for the item model
{% for item in Item_qs %}
<div class="col-lg-3 col-md-6 mb-4">
<!--Card image-->
<div class="view overlay">
<img src="{{ item.image.url }}" class="card-img-top"
alt="">
<a href="{{item.get_absolute_url}}">
<div class="mask rgba-white-slight"></div>
</a>
</div>
<!--Card image-->
</div>
<!--Card-->
{% end%}
and this is for the Women model
{% for items in women_qs %}
<!--Grid column-->
<div class="col-lg-3 col-md-6 mb-4">
<!--Card-->
<div class="card zoom">
<!--Card image-->
<div class="view overlay">
<img src="{{ items.image.url }}" class="card-img-top"
alt="">
<a href="{{items.get_absolute_url}}">
<div class="mask rgba-white-slight"></div>
</a>
</div>
</div>
<!--Card-->
</div>
{% endfor %}
i am using get_absoulte_url as the href link to get the Productpage.html
below is the code
def get_absolute_url(self):
return reverse("Ecommerce:product", kwargs={
'slug': self.slug })
My problem is how do I create a ProductDetailpage(Detailview) to get the details of individual items that is in the Item model and the Women model?
And how do I render both in the template
Please I believe my question is clear enough and if anyone need clarification I can explain further.
Looking forward for your assistance house😊
Ok, you can't use DetailView with multiple models. You'd be better off writing a normal View and allowing the URL for it take 2 params for each of your models.
Then you can get each instance in your view.
It'd work something like this;
urlpatterns = [
path('<int:item_id>/<int:women_id>', MultiModelView.as_view()),
]
class MultiModelView(View):
def __init__(self, **kwargs):
""" Constructor """
super().__init__(**kwargs)
self.item_id = None
self.women_id = None
def dispatch(self, request, *args, **kwargs):
self.item_id = self.kwargs.get('item_id')
self.women_id = self.kwargs.get('women_id')
return super().dispatch(request, *args, **kwargs)
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context.update({
'item': Item.objects.get(id=self.item_id),
'woman': Women.objects.get(id=self.women_id),
})
return context
I am not able to get photologue to show the images. What am I doing wrong?
development environment
django 2.1
python 3.5
osx, virtual_env, recent pip
settings.py
MEDIA_ROOT = os.path.join(BASE_DIR, 'mst/media/')
MEDIA_URL = "/media/"
urls
urlpatterns += [
...
url(r'^photologue/', include('photologue.urls', namespace='photologue')),
]
model
from photologue.models import Photo, Gallery
class PhotoExtended(models.Model):
photo = models.OneToOneField(Photo, on_delete=models.CASCADE, related_name='photo')
related_model = models.ForeignKey(MyModel, on_delete=models.CASCADE)
def __str__(self):
return self.photo.title
class GalleryExtended(models.Model):
gallery = models.OneToOneField(Gallery, on_delete=models.CASCADE, related_name='gallery')
related_model = models.ForeignKey(MyModel, on_delete=models.CASCADE)
def __str__(self):
return self.gallery.title
class based view
class MyModelList(ListView):
model = MyModel
template_name = "pictures.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['photos'] = PhotoExtended.objects.all()
context['galleries'] = GalleryExtended.objects.all()
return context
template (pictures.html):
{% block content %}
<ul>
{% for photoExtended in photos %}
<li>{{ photoExtended.photo.get_absolute_url }}</li>
<li>{{ photoExtended.photo.image }}</li>
<img src="/{{ photoExtended.photo.image }}" alt="{{ p.photo.title }}">
{% endfor %}
{% for gallery in galleries %}
<li></li>
{% endfor %}
shell response (per docs)
>>> from PIL import Image
>>>
notes
I migrated the database, and see the data in the database, and everything looks correct.
page renderings
photologue urls:
A single photo
the list of the photos
and the direct accessing of the image: (ra is the name in photologue, but em.jpeg is the file name)
and my view directly:
The template was wrong/outdated from an older version. Here is the correct usage in the template for an image within a list of images of type photologueExtended:
{% for photoExtended in photos %}
<!-- The link to the photologue template page with the photo and its gallery(s)-->
Link to page
<!-- The src link to the image thumbnail itself in the media url-->
<img src="{{ photoExtended.photo.get_thumbnail_url }}" />
<!-- The src link to the image itself in the media url-->
<img src="{{ photoExtended.photo.get_display_url }}" />
<!-- The photologue image's title/description/etc… -->
{{ photoExtended.photo.title }} <br>
{{ photoExtended.photo.description }} <br>
{% endfor %}
Also:
the url catchall in the main project urls.py was incorrect, and should be:
url(r'^$', indexView, name='indexView'),
Exception Value:
Cannot resolve keyword 'active' into field.
Choices are: billing_profile, billing_profile_id, brand, country, default, exp_month, exp_year, id, last4, stripe_id.
When i click on checkout button it show me that error.i already have a lot of models which are related to each other,i check all of them but i did not got any error so can you please verify them.
billing models.py
from django.conf import settings
from django.db import models
from django.db.models.signals import post_save,pre_save
from accounts.models import GuestEmail
import stripe
User=settings.AUTH_USER_MODEL
STRIP_SECRET_KEY= getattr(settings,"STRIP_SECRET_KEY","sk_test_I2eGCibhrZeFd9N0ipx9ac4I")
#STRIP_PUB_KEY=getattr(settings,"STRIP_PUB_KEY","pk_test_nvw3qh6iGMtKSGHMW5MHVwQD")
stripe.api_key=STRIP_SECRET_KEY
class BillingProfileManager(models.Manager):
def new_or_get(self,request):
user=request.user
guest_email_id=request.session.get('guest_email_id')
created=False
obj=None
if user.is_authenticated:
obj,created= self.model.objects.get_or_create(
user=user, email=user.email)
elif guest_email_id is not None:
guest_email_obj = GuestEmail.objects.get(id=guest_email_id)
obj, created = self.model.objects.get_or_create(
email=guest_email_obj.email)
else:
pass
return obj,created
class BillingProfile(models.Model):
user=models.OneToOneField(User,null=True,blank=True,on_delete=models.CASCADE)
email=models.EmailField()
active=models.BooleanField(default=True)
update = models.DateTimeField(auto_now=True)
timestamp=models.DateTimeField(auto_now_add=True)
customer_id=models.CharField(max_length=120,null=True,blank=True)
objects=BillingProfileManager()
def __str__(self):
return self.email
def charge(self,order_obj,card=None):
return Charge.objects.do(self,order_obj,card)
def get_cards(self):
return self.card_set.all()
#property
def has_card(self):
card_qs=self.get_cards()
return card_qs.exists()
#property
def default_card(self):
default_cards=self.get_cards().filter(default=True)
if default_cards.exists():
return self.default_cards.first()
return None
def billing_profile_created_receiver(sender,instance,*args,**kwargs):
if not instance.customer_id and instance.email:
print("ACTUAL AIL REQUEST SEND")
customer=stripe.Customer.create(
email=instance.email
)
print (customer)
instance.customer_id=customer.id
pre_save.connect(billing_profile_created_receiver,sender=BillingProfile)
class CardManager(models.Manager):
def all(self, *args, **kwargs): # ModelKlass.objects.all() --> ModelKlass.objects.filter(active=True)
return self.get_queryset().filter(active=True)
def add_new(self, billing_profile, token):
if token:
customer = stripe.Customer.retrieve(billing_profile.customer_id)
stripe_card_response = customer.sources.create(source=token)
new_card = self.model(
billing_profile=billing_profile,
stripe_id = stripe_card_response.id,
brand = stripe_card_response.brand,
country = stripe_card_response.country,
exp_month = stripe_card_response.exp_month,
exp_year = stripe_card_response.exp_year,
last4 = stripe_card_response.last4
)
new_card.save()
return new_card
return None
def user_created_receiver(sender,instance,created,*args,**kwargs):
if created and instance.email:
BillingProfile.objects.get_or_create(user=instance,email=instance.email)
post_save.connect(user_created_receiver,sender=User)
class ChargeManager(models.Manager):
def do(self, billing_profile, order_obj, card=None): # Charge.objects.do()
card_obj = card
if card_obj is None:
cards = billing_profile.card_set.filter(default=True) # card_obj.billing_profile
if cards.exists():
card_obj = cards.first()
if card_obj is None:
return False, "No cards available"
c = stripe.Charge.create(
amount = int(order_obj.total * 100), # 39.19 --> 3919
currency = "usd",
customer = billing_profile.customer_id,
source = card_obj.stripe_id,
metadata={"order_id":order_obj.order_id},
)
new_charge_obj = self.model(
billing_profile = billing_profile,
stripe_id = c.id,
paid = c.paid,
refunded = c.refunded,
outcome = c.outcome,
outcome_type = c.outcome['type'],
seller_message = c.outcome.get('seller_message'),
risk_level = c.outcome.get('risk_level'),
)
new_charge_obj.save()
return new_charge_obj.paid, new_charge_obj.seller_message
class Charge(models.Model):
billing_profile = models.ForeignKey(BillingProfile,on_delete=models.CASCADE)
stripe_id = models.CharField(max_length=120)
paid = models.BooleanField(default=False)
refunded = models.BooleanField(default=False)
outcome = models.TextField(null=True, blank=True)
outcome_type = models.CharField(max_length=120, null=True, blank=True)
seller_message = models.CharField(max_length=120, null=True, blank=True)
risk_level = models.CharField(max_length=120, null=True, blank=True)
objects = ChargeManager()
class Card(models.Model):
billing_profile=models.ForeignKey(BillingProfile,on_delete=models.CASCADE)
stripe_id=models.CharField(max_length=120)
brand=models.CharField(max_length=120,null=True,blank=True)
country = models.CharField(max_length=12, null=True, blank=True)
exp_month=models.IntegerField(null=True,blank=True)
exp_year=models.IntegerField(null=True,blank=True)
last4=models.CharField(max_length=4,null=True,blank=True)
default=models.BooleanField(default=True)
objects = CardManager()
def __str__(self):
return "{} {}".format(self.brand, self.last4)
checkout.html
{% extends "base.html" %}
{% block content %}
{% if not billing_profile%}
<div class="row text-center">
<div class="col-12 col-md-6">
<p class="lead">Login</p>
{% include 'accounts/snippets/form.html' with form=login_form next_url=request.build_absolute_uri %}
</div>
<div class="col-12 col-md-6">
Continue as Guest
{% url "guest_register" as guest_register_url %}
{% include 'accounts/snippets/form.html' with form=guest_form next_url=request.build_absolute_uri action_url=guest_register_url %}
</div>
</div>
{% else %}
{% if not object.shipping_address %}
<div class="row">
<div class="col-12">
<p class="lead">Shipping Address</p>
<hr/>
</div>
<div class="col-6">
{% url "checkout_address_create" as checkout_address_create %}
{% include 'addresses/form.html' with form=address_form next_url=request.build_absolute_uri action_url=checkout_address_create address_type='shipping' %}'
</div>
<div class="col-6">
{% url 'checkout_address_reuse' as checkout_address_reuse %}
{% include 'addresses/prev_addresses.html' with address_qs=address_qs next_url=request.build_absolute_uri address_type='shipping' action_url=checkout_address_reuse %}
</div>
</div>
{% elif not object.billing_address %}
<div class="row">
<div class="col-12">
<p class="lead">Billing Address</p>
<hr/>
</div>
<div class="col-md-6">
{% url "checkout_address_create" as checkout_address_create %}
{% include 'addresses/form.html' with form=address_form next_url=request.build_absolute_uri action_url=checkout_address_create address_type='billing' %}
</div>
<div class="col-6">
{% url 'checkout_address_reuse' as checkout_address_reuse %}
{% include 'addresses/prev_addresses.html' with address_qs=address_qs next_url=request.build_absolute_uri address_type='billing' action_url=checkout_address_reuse %}
</div>
</div>
{% else%}
{% if not has_card %}
<!-- enter credit card here -->
<div class='stripe-payment-form' data-token='{{ publish_key }}' data-next-url='{{ request.build_absolute_uri }}' data-btn-title='Add Payment Method'></div>
{% else %}
<h1>Finalize Checkout</h1>
<p>Cart Item:{% for product in object.cart.products.all %}{{ product}}{% if not forloop.last %},{% endif %},{% endfor %}</p>
<p>Shipping Address:{{object.shipping_address.get_address}}</p>
<p>Billing Address:{{object.shipping_address.get_address}}</p>
<p>Cart Total:{{object.cart.total}}</p>
<p>Shipping Total:{{object.shipping_total}}</p>
<p>Order Total:{{object.total}}</p>
<form class="form" method="POST" action="">{% csrf_token %}
<button type="submit btn btn-success">Checkout</button>
</form>
{% endif %}
{% endif %}
{% endif %}
{% endblock %}
The problem appears to be in your CardManager declaration.
class CardManager(models.Manager):
def all(self, *args, **kwargs):
return self.get_queryset().filter(active=True)
active is not a field on the Card model, but rather on the BillingProfile FK from the Card model.
Change this to:
class CardManager(models.Manager):
def all(self, *args, **kwargs):
return self.get_queryset().filter(billing_profile__active=True)
That is likely to happen because you are trying to filter a queryset by an attribute its model does not have.
The model missing this attribute is the one having the attributes are shown to you by the traceback:
billing_profile, billing_profile_id, brand, country, default, exp_month, exp_year, id, last4, stripe_id.
that is, model Card.
Add something like:
active = models.BooleanField(default=True)
to Card model, then makemigrations, migrate, and it should work.