Display user`s protrait from model in template in django - python

I want to display the the user protrait of the user in the templates.
models.py
class Profile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL, on_delete=models.CASCADE)
date_of_birth = models.DateField(blank=True, null=True)
photo = models.ImageField(upload_to='user/%Y/%m/%d/', blank=True)
views.py
#login_required
def dashboard(request):
# Display all actions by default
actions = Action.objects.exclude(user=request.user)
following_ids = request.user.following.values_list('id',
flat=True)
if following_ids:
# If user is following others, retrieve only their actions
actions = actions.filter(user_id__in=following_ids)
actions = actions.select_related('user', 'user__profile')\
.prefetch_related('target')[:10]
return render(request,
'account/dashboard.html',
{'section': 'dashboard',
'actions': actions})
tempate:
<img src="{{ Profile.photo.url }} " height="40" width="40"/>

You can use:
<img src="{{ request.user.profile.photo.url }} " height="40" width="40"/>
as you have a One-to-One relationship between the django's User model and your Profile model.

Related

How to show history of orders for user in Django

I will pin some screenshots of my template and admin panel
I have history of orders in admin panel but when im trying to show title and img of order product in user profile in my template that`s not working and i got queryset
Im sorry for russian words in my site, i can rescreen my screenshots if you need that
models.py
class Order(models.Model):
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name='orders', verbose_name='Заказы',
default=1)
username = models.CharField(max_length=50, verbose_name='Имя пользователя')
email = models.EmailField()
vk_or_telegram = models.CharField(max_length=255, verbose_name='Ссылка для связи', default='vk.com')
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
paid = models.BooleanField(default=False, verbose_name='Оплачено')
class Meta:
ordering = ['-created',]
verbose_name = 'Заказ'
verbose_name_plural = 'Заказы'
def __str__(self):
return 'Заказ {}'.format(self.id)
def get_cost(self):
return sum(item.get_cost() for item in self.items.all())
class OrderItem(models.Model):
order = models.ForeignKey(Order, related_name='order', on_delete=models.CASCADE)
product = models.ForeignKey(Posts, related_name='order_items', on_delete=models.CASCADE)
price = models.DecimalField(max_digits=10, decimal_places=2)
def __str__(self):
return '{}'.format(self.id)
def get_cost(self):
return self.price
views.py
#login_required
def profile(request):
user_orders = Order.objects.filter(user=request.user)
data = {
'user_orders': user_orders,
}
return render(request, 'store/main_pages/profile.html', data)
order history template:
{% for item in user_orders %}
{{ item }}
{{ item.order.all }}
{% endfor %}
Profile template
admin order panel
Create a model for storing the orders. This model should have fields for storing information about the order, such as the total cost, the date the order was placed, and the status of the order.
Create a view that will display the order history for a user. This view should retrieve all of the orders for the logged-in user from the database and pass them to a template.
Create a template to display the order history. This template should loop through the list of orders passed to it by the view and display the relevant information for each order.
Add a URL pattern to your Django project's urls.py file that maps to the view that displays the order history.
Add a link to the order history page in your application's navigation menu or elsewhere on the site.
In user_orders = Order.objects.filter(user=request.user)
you have all of the user's order histories.
when sending these data to the front, don't use {{ item.order.all }}
each of your items is an order.
I found solution, OrderItem has product, which is a ForeignKey for my product with title, content and img
Views.py changed for:
#login_required
def profile(request):
user_orders = Order.objects.filter(user=request.user)
user_order_item = OrderItem.objects.all()
data = {
'user_orders': user_orders,
'user_order_item': user_order_item,
}
return render(request, 'store/main_pages/profile.html', data)
Template:
{% if user_orders %}
{% for item in user_order_item %}
<p>{{ item.product.title }}</p>
<p><img src="{{ item.product.photo.url }}" alt=""></p>
% endfor %}
{% endif %}

Django Model Multi Select form not rendering properly

I am trying to display all the categories to appear as a list that I can click and select from, just an exact replica of what I have in my admin panel, but it still display's as a list that isn't clickable.
forms.py
class ProfileEditForm(forms.ModelForm):
"""
Form for updating Profile data
"""
class Meta:
model = Profile
fields = [
"first_name",
"last_name",
"about_me",
"profile_image",
"username",
"email",
"categories",
]
first_name = forms.CharField(label="First Name", max_length=63, required=False)
last_name = forms.CharField(label="Last Name", max_length=63, required=False)
about_me = forms.CharField(label="About Me", max_length=511, required=False)
email = forms.EmailField(label="Email", disabled=True)
username = forms.CharField(label="Username", disabled=True)
profile_image = forms.ImageField(required=False)
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)
profile.models.py
class Profile(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile")
first_name = models.CharField(max_length=63, blank=False)
last_name = models.CharField(max_length=63, blank=False)
about_me = models.CharField(max_length=511, blank=True)
categories = models.ManyToManyField(
Category, related_name="user_categories", symmetrical=False
)
categories.models.py
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=63)
created = models.DateTimeField(auto_now_add=True, blank=True, null=True)
last_modified = models.DateTimeField(auto_now=True, blank=True, null=True)
def __str__(self):
return self.name
def __unicode__(self):
return self.name
class Meta:
verbose_name_plural = "Categories"
settings.html
<div class='row'>
<div class="col s12 m6">
{{form.categories.errors}}
{{form.categories.label_tag}}
{{form.categories}}
</div>
</div>
What I hope to achieve
What I get
You need to create the form itself:
<form method='post'>
</form>
And print each field on a new line:
{{ form.as_p }}
is a security check.
{% csrf_token %}
In the view, I left get_context_data. In it, you can add values ​​to the context, for example, like this:
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['rubrics'] = Car.objects.all()
Replace bboard with the name of the folder where your templates are placed.
I have this: templates/bboard which are in the application folder.
In the view for the form, the CreateView class is used, in which: template_name - the name of the template for displaying the page, form_class - the form class is indicated, success_url - where to return in case of successful saving of the form (in this case, this is the same page with the form), get_context_data - the template context (you can print it out and see what's inside).
And if your model has fields: first_name, last_name, about_me, email, username, profile_image, then it is enough that you have specified the fields variable in the class Meta class. You don't need to re-create them in the form.
template_name = 'bboard/tam_form.html'#bboard replace with your prefix
Templates
<form method='post'>
{{form.categories.errors}}
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value='adding'>
</form>
views.py
from .forms import *
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy
class Profile(CreateView):
template_name = 'bboard/settings.html'#bboard replace with your prefix
form_class = ProfileEditForm
success_url = reverse_lazy('test')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
return context
urls.py
from django.urls import path
from .views import *
urlpatterns = [
path('test/', Profile.as_view(), name='test'),
]
Update 13.11.2022
This is how my form looks like when I go to the address:
http://localhost:8000/test/
But the form is not submitted. I don't have much experience with this. I can assume that forms.ModelForm expects that the model has such fields, because if you delete the lines with email, username, profile_image and also remove them from the fields and add 'user' to the field, then the data will be saved in the database (checked).
As I said earlier, if the fields are declared in fields, then you do not need to define them again (if you leave them, the form will also be saved). This is what the form class looks like:
class ProfileEditForm(forms.ModelForm):
class Meta:
model = Profile
fields = [
'user',
'first_name',
'last_name',
'about_me',
'categories',
]
categories = forms.ModelMultipleChoiceField(
queryset=Category.objects.all(),
required=False,
widget=forms.CheckboxSelectMultiple(),
)

How to view multiple images under separate posts in profile page?

I am building a social media website. On the profile page and home page are different posts. Each can have multiple images. I created a different model for images and set ForeignKey to Post model. The form for uploading text and images works fine because the images attach to each post in the database.
However, I am having issues writing the views code for the page they are to display. I am getting just text with no images.
I am trying to add an Id to each post in the views but I have no idea how to do that since they are all in one page and therefore have no separate urls.
I don't know if that is the right approach.
models.py
class Tweets(models.Model):
user = models.ForeignKey(User, on_delete=models.CASCADE)
profile = models.ForeignKey(Profile, on_delete=models.CASCADE)
note = models.TextField(blank=False,)
date_posted = models.DateTimeField(auto_now_add=True)
url = models.URLField(max_length=200, blank=True)
likes = models.IntegerField(default=0)
def __str__(self):
# if len(self.note) > 60:
# return f"{self.note[:60]}... --- (Posted {self.when_tweeted} ago) by [{self.profile.name}]"
# if self.when_tweeted.title() == "Just Now":
# return f"{self.note[:60]}... --- (Posted {self.when_tweeted}) by [{self.profile.name}], {self.likes} likes"
# else:
# if self.when_tweeted == "Just Now":
# return f"{self.note[:60]}... --- (Posted {self.when_tweeted}) by [{self.profile.name}]"
# return f"{self.note} --- (Posted {self.when_tweeted} ago) by [{self.profile.name}]"
return f"{self.note}({self.id})"
class Meta:
ordering = ['-date_posted']
verbose_name_plural = 'Tweets'
#property
def tweet_id(self):
return self.id
class Images(models.Model):
tweet = models.ForeignKey(Tweets, on_delete=models.CASCADE, related_name='images')
image = models.ImageField(blank=True, upload_to='image/tweets_image')
class Meta:
verbose_name = 'Image'
verbose_name_plural = 'Images'
def __str__(self):
return self.image.url
views.py
def profile_index(request, user_id, *args, **kwargs):
users = User.objects.all()
profiles = Profile.objects.all()
user = get_object_or_404(User, id=user_id)
profile = get_object_or_404(Profile, id=user_id)
tweets = Tweets.objects.all().filter(user=user)
id_list = []
for t in tweets:
id=t.id
print(id)
id_list.append(id)
print(id_list)
target_tweet = get_object_or_404(Tweets, id=id)
tweet_images = target_tweet.images.all()
context = {
'user': user,
'profile': profile,
'tweets': tweets,
'users': users,
'profiles': profile,
'target_tweet': target_tweet,
'tweet_images': tweet_images
}
return render(request, 'twee/profile_index.html', context)
profile.html
{% if tweet == target_tweet %}
{% for img in tweet_images %}
<img class="post-image" src="{{ img.image.url }}" alt="">
{% endfor %}
{% endif %}

Unable to automatically pick foreign key from modelform

I am working on a product app on Python 2.7 / Django 1.7.
I have a model for product namely 'product_profile' and I want to allow my customer (end user) to ask any thing regarding specific products using a form.
However I am unable to allow user to automatically select the product (foreign key) and the customer has to select from a drop-down which quite irrational. I have also assigned the foreign key in url-variable.
here is my code:
MODEL.PY
class ProductProfile(models.Model):
category = models.ForeignKey(Category)
brand = models.ForeignKey(Brand)
product_name = models.CharField(max_length=128)
model_name = models.CharField(max_length=128)
generation = models.CharField(max_length=128)
processor = models.CharField(max_length=128)
ram = models.DecimalField(max_digits=2, decimal_places=0)
hdd = models.DecimalField(max_digits=6, decimal_places=2)
optical_drive = models.CharField(max_length=128)
display = models.CharField(max_length=128)
card_reader = models.CharField(max_length=128)
blue_tooth = models.CharField(max_length=128)
web_cam = models.CharField(max_length=128)
warranty = models.CharField(max_length=128)
price = models.DecimalField(max_digits=9, decimal_places=2)
condition = models.TextField()
product_image = models.ImageField(upload_to=update_Product_image_filename)
post_date = models.DateTimeField(db_index=True, auto_now_add=True)
# Override th __unicode__() method to return out something meaningful!
def __unicode__(self):
return self.product_name
class Customer_ps_contact(models.Model):
name = models.CharField(max_length=128)
email = models.EmailField(max_length=75)
subject = models.CharField(max_length=128 )
product = models.ForeignKey(ProductProfile)
message = models.TextField()
phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format:
'+999999999'. Up to 15 digits allowed.")
phone_number = models.CharField(validators=[phone_regex], blank=True, max_length=15) # validators should be a
list
def __unicode__(self):
return self.name
FORM.PY
class Customer_ps_contactForm(forms.ModelForm):
class Meta:
model = Customer_ps_contact
product = forms.ModelChoiceField(queryset=ProductProfile.objects.all(),
widget=forms.HiddenInput())
fields = ('name','email', 'product','subject','message', 'phone_number')
VIEWS.PY
def product_inquiry(request, product_id):
product = ProductProfile.objects.get(pk=product_id)
if request.method == 'POST':
#form = Customer_ps_contactForm(request.POST, initial = {'product': product})
#form = Customer_ps_contactForm(initial = {'product': product.id})
form = Customer_ps_contactForm(request.POST)
if form.is_valid():
form_data_dict = form.cleaned_data
print form_data_dict['product']
mail_customer_enquriy(form_data_dict) # Function to send email to admin
thank_u_customer(form_data_dict) # Function to send email to customers
form = form.save(commit=False)
form.product = product
form.save()
return home(request)
else:
print ("form is not valid")
print (form.errors)
else:
form = Customer_ps_contactForm()
context_dict = {'form':form, 'product': product}
return render(request, 'product/product_inquiry2.html',context_dict)
URL Patterns
urlpatterns = patterns('',
url(r'^inquiry/(?P<product_id>\d+)/$', views.product_inquiry, name='price'), # Only relevent url given
)
Template : product_inquiry2.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block body_block %}
{% block title %}Product Inquiry{% endblock %}
<div class="row">
<div class="col-md-10 col-md-offset-1">
<h2 style="font-weight:bold">Enquiry regarding '{{product.product_name}}'</h2>
<hr>
<form id="contact_form" method="post" action=""/>
{% csrf_token %}
{{ form | crispy }}
<input class="btn btn-primary pull-right " type="submit" name="submit" value="Submit the Message" />
</form>
</div>
</div>
{% endblock %}
What should I do?
You know what the product is from the id in the url, so there's no need to include it in your form.
To check that the product exists in the database, you can use the get_object_or_404 shortcut.
def product_inquiry(request, product_id):
product = get_object_or_404(ProductProfile, pk=product_id)
Then leave out 'product' from your list of fields, and remove the ModelChoiceField with hidden input widget.
class Customer_ps_contactForm(forms.ModelForm):
class Meta:
model = Customer_ps_contact
fields = ('name','email','subject','message','phone_number')
You are already setting the product when you save it, but it would be clearer to use the variable name instance to make it clearer what's going on. If you change your mail_customer_enquriy and thank_u_customer methods to use the instance instead of cleaned_data, then you won't have to do anything with form.cleaned_data.
if form.is_valid():
instance = form.save(commit=False)
instance.product = product
instance.save()
mail_customer_enquriy(instance) # Function to send email to admin
thank_u_customer(instance) # Function to send email to customers
return home(request)

Problem with forms and Photologue

I'm using Pinax to create a new project. For this project I needed to create a new app 'Business' which is much like Profiles but they wanted to keep everything seperate for Businesses.
I'm trying to have the admin be able to change the logo or "avatar" for the business profile. Im using the ImageModel class from Photologue to control the image upload, etc but I ran into a problem. When going through the form, the form goes through and redirects but the image doesn't actually get updated. When you go through the django admin, the image uploads fine.
If someone could take a look and see if something is missing, I've been staring at it for too long, so I need a fresh pair of eyes.
Business Models.py
class Business(models.Model):
name = models.CharField(verbose_name="Name", max_length=140)
desc = models.TextField(verbose_name="Description", null=True, blank=True)
bus_type = models.CharField(verbose_name="Business Type", choices=BUSINESS_TYPES, max_length=20)
location = models.CharField(_("location"), null=True, blank=True, max_length=200)
website = models.URLField(_("website"), null=True, blank=True, verify_exists=False)
created_by = models.ForeignKey(User, related_name="Created By")
admin = models.ManyToManyField(User, related_name="Admin User", null=True, blank=True)
followers = models.ManyToManyField(User, related_name="Followed by", null=True, blank=True)
date_added = models.DateField(verbose_name="Date Added")
class Meta:
verbose_name = "Business"
verbose_name_plural = "Businesses"
def __unicode__(self):
return self.name
class BusinessLogo(ImageModel):
business = models.ForeignKey(Business, related_name="Business Association")
My views.py
#login_required
def changeLogo(request, bus_id):
user = request.user
b = get_object_or_404(Business, pk = bus_id)
if request.method == 'POST':
form = ChangeLogoForm(request.POST, request.FILES, instance = b)
if form.is_valid():
biz_logo = form.save(commit=False)
biz_logo.save()
return HttpResponseRedirect('/')
else:
form = ChangeLogoForm()
return render_to_response('business/changelogo.html',
{'user': user, 'form':form, 'b':b}, context_instance=RequestContext(request))
Forms.py
class ChangeLogoForm(ModelForm):
class Meta:
model = BusinessLogo
def save(self, force_insert=False, force_update=False, commit=True):
f = super(ChangeLogoForm, self).save(commit=False)
if commit:
f.save()
print "form save method was called with commit TRUE"
return f
And finally my changelogo.html
...
{% block body %}
<h1>Change Logo</h1>
<form method="POST" action="" enctype="multipart/form-data">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Upload">
</form>
{% endblock %}
...
Thanks everyone, for taking a look.
Steve
The ChangeLogoForm's model is BusinessLogo, but when calling it's constructor you pass it a Business instance:
b = get_object_or_404(Business, pk = bus_id)
...
form = ChangeLogoForm(request.POST, request.FILES, instance = b)
(And you should probably use a OneToOneField field instead of ForeignKey)

Categories

Resources