thanks for your time:
I've got a model that is linked to the user and the only one that can update him its his creator. untill that works fine. just the creator user can open the url update although i'm not beeing able to pass a button on the main template of the model with redirect to that update url.
i'd like to know if there is a way to that button apear just to his user (if not ok, to get in just open to the matching queryset user).
Or just why this button ain't working: i should get the url eg:services/parceiro/update/2 i'm beeing able to open this url if i'm the creator user but when i try to set it in a button i get this error:
Reverse for 'update_parceiro2' with arguments '('',)' not found. 1 pattern(s) tried: ['services/parceiro/update/(?P[0-9]+)$']
parceiros.html:
{% extends "base.html" %}
{% block content %}
<h1>{{parc.nome}} - {{parc.user}} - {{parc.responsavel}}</h1>
<form action="{% url 'update_parceiro2' Parceiros.id %}">
<button type="submit"><i class="material-icons">sync</i></button>
</form>
{% endblock %}
views.py:
def parceirosview(request, pk=None):
parc = get_object_or_404(Parceiros, id=pk)
context = {'parc': parc}
return render(request, 'parceiro.html', context)
def get_queryset(self):
return super().get_queryset().filter(parceiro__user=self.request.user)
class ParceiroUpdate(UpdateView):
model = Parceiros
template_name = 'parceiroform.html'
fields = ['nome', 'endereco', 'responsavel', 'tel']
def get_queryset(self):
return super().get_queryset().filter(user=self.request.user)
urls.py:
urlpatterns = [
path('home/', views.home_view, name='home2'),
path('parceiro/', views.parceirosview, name='parceiro2'),
path('parceiro/detail/<int:pk>', views.parceirosview, name='parceiro_detail2'),
path('addparceiro/', views.parceiros_create, name='add_parceiro2'),
path('parceiro/detail2/<int:pk>', ParceirosView.as_view(), name='parceiro_detail22'),
path('parceiro/update/<int:pk>', ParceiroUpdate.as_view(), name='update_parceiro2')
]
models.py:
get_user_model = User
class Parceiros (models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
nome = models.CharField(max_length=200)
endereco = models.TextField(max_length=400, blank=True)
responsavel = models.CharField(max_length=100)
tel = PhoneField(max_length=12)
created_at = models.DateTimeField(auto_now=True)
updated_at = models.DateTimeField(auto_now_add=True, blank=True)
ativo = models.BooleanField(default=False)
def get_queryset(self):
queryset = super(Parceiros, self).get_queryset()
return queryset
def __str__(self):
return '%s %s' % (self.user, self.nome)
def get_absolute_url(self):
return reverse('parceiro_detail2', kwargs={'pk': self.pk})
You can use this code in your template to display content for user based on his id
{% if request.user.id == 1 %}
<form action="{% url 'update_parceiro2' Parceiros.id %}">
<button type="submit"><i class="material-icons">sync</i></button>
</form>
{% endif %}
Related
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 %}
I want to add review function in movie_detail.html, but I don't know how to query comments and map to movie_detail.It returns Reverse for 'add_review' with arguments '('',)' not found error.
My url.py:
urlpatterns = [
path('', MovieList.as_view(), name='movie_list'),
path('<int:pk>', MovieDetail.as_view(), name='movie_detail'),
path('search/', MovieSearch.as_view(), name='movie_search'),
path('addreview/<int:id>/', views.add_review, name='add_review'),
]
My model.py:
class Movie(models.Model):
title = models.CharField(max_length=200)
actors = models.CharField(max_length=500, null=True)
poster_url = models.CharField(max_length=200)
director = models.CharField(max_length=200, default='')
score = models.FloatField()
genres = models.CharField(max_length=200)
language = models.CharField(max_length=200, default='English')
durations = models.IntegerField(default=0)
regions = models.CharField(max_length=200, default='')
release_date = models.DateField(default=timezone.now)
description = models.TextField(max_length=1000, default='')
year = models.IntegerField(default=2000)
views_count = models.IntegerField(default=0)
created = models.DateTimeField(default=timezone.now)
def __str__(self):
return self.title
def genres_as_list(self):
genre_list = self.genres.split('/')
return genre_list
def actors_as_list(self):
return self.actors.split('/')
class Review(models.Model):
movie = models.ForeignKey(Movie, on_delete=models.CASCADE)
user = models.ForeignKey(User, on_delete=models.CASCADE)
comments = models.TextField(max_length=1000)
rating = models.FloatField(default=0)
data_added = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.user.username
my view.py:
class MovieDetail(DetailView):
model = Movie
template_name = "main/movie_detail.html"
def get_object(self):
object = super().get_object()
object.views_count += 1
object.save()
return object
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['links'] = MovieLinks.objects.filter(movie=self.get_object())
context['related_movies'] = Movie.objects.filter(genres__in=self.get_object().genres_as_list()).order_by(
'created')[0:6]
# context['reviews'] = Review.objects.filter(id=self.kwargs['pk'])
return context
class MovieSearch(ListView):
model = Movie
paginate_by = 20
template_name = "main/movie_list.html"
def get_queryset(self):
query = self.request.GET.get('query')
if query:
object_list = self.model.objects.filter(title__icontains=query)
else:
object_list = self.model.objects.none()
return object_list
#login_required
def add_review(request, id):
movie = Movie.objects.get(id=id)
if request.method != "POST":
form = ReviewForm(request.POST or None)
if form.is_valid():
data = form.save(commit=False)
data.comment = request.POST["comment"]
data.rating = request.POST["rating"]
data.user_id = request.user.pk
data.movie_id = movie.pk
data.save()
return redirect("main:movie_detail", id)
else:
form = ReviewForm()
context = {"form": form}
return render(request, 'main/movie_detail.html', context)
my movies_detail.html review part:
<section class="comments">
<h3>Comment</h3>
<div class="card">
<div class="card-body">
<h3 class="text-center">Add Review</h3>
<form method="POST" action="{% url 'main:add_review' movie.id%}">
{% csrf_token %}
<label for="comment">Review</label>
<textarea name="comment" id="comment" cols="30" rows="5" class="form-control"></textarea>
<label for="rating">Rating</label>
<input type="text" name="rating" class="form-control">
<br>
<input type="submit" class="btn btn-danger" value="Add Review">
</form>
</div>
</div>
I want add the review function and I code the add_review in view.py by some tutorial.But I don't know how to fix it.
You are not passing the movie object to template, so movie.id evaluates to an empty to string, which causes the exception you are seeing.
Try this:
#login_required
def add_review(request, id):
movie = Movie.objects.get(id=id)
...
context = {"form": form, "movie": movie}
return render(request, 'main/movie_detail.html', context)
Edit: alternatively, you can just set action="" as shah sawood pointed out in his answer.
On a side note: Welcome to Stack Overflow! Next time, please post the full stacktrace, that increases your chances of getting an answer to your problem :)
Note
When you want to post data a view that it renders you need not to specify action but rather leave as action=""
You're getting the error because you're not passing a movie to the context in the last 2 lines of add_review. You need to update it to
context = {"form": form, "movie": movie}
return render(request, 'main/movie_detail.html', context)
I have a problem when I want to update an existing object... in another project, I used a similar lines of code, but now, it doesn't work when I'm going to save the actual information...
the more stranger thing is... at the end says The current path, editEstHab/, didn't match any of these., but when I search on my project, the only time that I use editEstHab/ is in urls.py...
So... help :( I don't have any clue about what is my mistake.
models.py
class habitacion(models.Model):
nroHabitacion = models.IntegerField(null=False)
tipoHabitacion = models.CharField(max_length=70, null=True)
tipoCama = models.ForeignKey(tipoCama, on_delete=models.CASCADE, blank=True, null=False)
accesorios = models.CharField(max_length=70, null=True)
precio = models.IntegerField(null=False)
estado_habitacion = models.ForeignKey(estadoHab, on_delete=models.CASCADE, blank=True, null=True)
def __str__(self):
return self.tipoHabitacion
forms.py
class UpdateHabForm(forms.ModelForm):
class Meta:
model = habitacion
fields = ['estado_habitacion']
views.py
def editHab(request,id_habitacion):
# llamando datos de habitacion seleccionada
hab = habitacion.objects.get(id=id_habitacion)
if request.method == 'GET':
form = UpdateHabForm(instance=hab)
else:
form = UpdateHabForm(request.POST, instance=hab)
if form.is_valid():
form.save()
context = {
'form' : form,
'hab' : hab
}
return render(request,"editEstHab.html",context)
urls.py
path('editEstHab/<id_habitacion>', views.editHab, name="editEstHab"),
Error ScreenShot
It seems like the error is the url of the POST request
If you leave the action attribute of the html form blank, it should work fine
<form class="" action="" method="post">
{% csrf_token %}
{% for field in form %}
{{field}}
{% endfor %}
<button type="submit" name="button">UPDATE</button>
</form>
I am getting an error - Reverse for 'add_comment' with keyword arguments '{u'slug': None}' not found. 1 pattern(s) tried: [u'blog/(?P\d+)/comment/$']
I added - app_name= 'blog' - to urls to solve the earlier error of namespace
but now I am stuck with a new error
my urls.py
url(r'^(?P<pk>\d+)/comment/$', views.add_comment, name='add_comment')
my views.py
def add_comment(request, slug):
post = get_object_or_404(Post, slug=slug)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.post = post
comment.save()
return redirect('blog:post', slug=post.slug)
else:
form = CommentForm()
template = 'blog/add_comment.html'
context = {'form': form}
return render(request, template, context)
my models.py
class Post(models.Model):
title = models.CharField(max_length=200)
body = models.TextField()
date = models.DateTimeField()
slug = models.SlugField(max_length=250, blank=True, null=True)
def __unicode__(self):
return self.title
def save(self, *args, **kwargs):
self.slug = slugify(self.title)
super(Post, self).save(*args, **kwargs)
def get_absoulte_url(self):
return reverse('blog:post.html', args=[self.slug])
class Comment(models.Model):
post = models.ForeignKey(Post, related_name='comments', blank=True,
null=True)
user = models.CharField(max_length=250)
email = models.EmailField()
body = models.TextField()
created = models.DateTimeField(auto_now_add=True)
approved = models.BooleanField(default=False)
def approved(self):
self.approved = True
self.save()
def __str__(self):
return self.user
my template add_comment.html
{% extends "personal/header.html" %}
{% block content %}
<h1>Add new comment</h1>
<form method='POST'>{% csrf_token %}
{{ from.as_p }}
<button type='submit'>Submit</button>
</form>
{% endblock %}
This is coming from a page where you had given the link to add comment, most probably in the detailed blog/post page.
You are creating the add comment URL without passing the pk argument to it.
It should be something like.
Add Comment
But you have missed blog.pk or something like post.pk in creating URL.
Just do that and error will be resolved.
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)