I 'slugified' the team_name field for model Team so that spaces would display more beautifully in the URL. However when I try to switch the pk variable that you pass into the URL, I get a NoReverseMatch for the slug. It is working fine for with team_name.
models
class Team(models.Model):
team_name = models.CharField(max_length=25, unique=True)
team_name_slug = models.SlugField(max_length=25, unique=True)
views + template URL (this doesn't work)
def team_public_profile(request, pk):
team = get_object_or_404(Team, team_name_slug=pk)
... other code
---
<form action="{% url 'team_public_profile' pk=team_name_slug %}">
this works
def team_public_profile(request, pk):
team = get_object_or_404(Team, team_name=pk)
... other code
---
<form action="{% url 'team_public_profile' pk=team_name %}">
First of all, you need to populate the team_name_slug using django.utils.text.slugify on the Team model save() method like:
from django.utils.text import slugify
class Team(models.Model):
...
def save(self, *args, **kwargs):
if self.team_name:
self.team_name_slug = slugify(self.team)
super(Team, self).save(*args, **kwargs)
Your URL should look like:
url(r'^teams/(?P<team_name_slug>[\w-]+)/$', views.team_public_profile, name='team_public_profile')
And your View + Template:
def team_public_profile(request, team_name_slug):
team = get_object_or_404(Team, team_name_slug=team_name_slug)
... other code
<form action="{% url 'team_public_profile' team_name_slug=team_name_slug %}">
Related
I am trying to allow users to save details of a workout for a specific exercise through submitting a form. My ExerciseDetailView displays the form how I'd like it to:
class ExerciseDetailView(DetailView):
model = Exercise
template_name = 'workouts/types.html'
def get_context_data(self, **kwargs):
context = super(ExerciseDetailView, self).get_context_data(**kwargs)
context['form'] = WorkoutModelForm
return context
But my problem is with saving the inputted data in the database. I have tried making both a FormView and a CreateView but am clearly missing something:
class ExerciseFormView(FormView):
form_class = WorkoutModelForm
success_url = 'workouts:exercise_detail'
def form_valid(self, form):
form.save()
return super(ExerciseFormView, self).form_valid(form)
Here is my referenced WorkoutModelForm:
class WorkoutModelForm(forms.ModelForm):
class Meta:
model = Workout
fields = ['weight', 'reps']
My template:
<form action="{% url 'workouts:workout' exercise.id %}" method="post">
{% csrf_token %}
{{ form }}
<button type="submit">Save</button>
</form>
Urls:
path('exercise/<int:pk>/detail/', ExerciseDetailView.as_view(), name='exercise_detail'),
path('exercise/<int:pk>/detail/', ExerciseFormView.as_view(), name='workout'),
And for context here is my Workout model which contains a get_absolute_url method:
class Workout(models.Model):
weight = models.FloatField(default=0)
reps = models.PositiveIntegerField(default=0)
created = models.DateField(auto_now_add=True)
updated = models.DateField(auto_now=True)
exercise = models.ForeignKey(Exercise, on_delete=models.CASCADE, default=None)
def get_absolute_url(self):
return reverse('exercise_detail', args=[str(self.pk)])
I am not receiving any errors, but when I submit the form my url remains the same, as I hoped, however the page just appears blank and the objects are not recorded. Can anybody please help me see what the problem is?
The problem is not your view, the Django logic will never trigger this view, the URLs are perfectly overlapping, so that means that for a URL, it will always trigger the first view (here the ExerciseDetailView), you should make the paths non-overlapping, for example with:
path('exercise/<int:pk>/detail/', ExerciseDetailView.as_view(), name='exercise_detail'),
path('exercise/<int:pk>/workout/', ExerciseFormView.as_view(), name='workout'),
Triggering the logic will however not be sufficient, since it will not link the Workout to the necessary exercise, you can alter the logic to:
from django.urls import reverse
class ExerciseFormView(CreateView):
form_class = WorkoutModelForm
def form_valid(self, form):
form.instance.exercise_id = self.kwargs['pk']
return super().form_valid(form)
def get_success_url(self):
return reverse('workouts:exercise_detail', kwargs={'pk': self.kwargs['pk']})
Need use CreateView
from django.views.generic.edit import CreateView
class ExerciseFormView(CreateView):
form_class = WorkoutModelForm
...
I created a ModelForm which renders correctly and displayed but whenever i try to submit the form I get a 405 error and the page doesnt redirect to success page.
Ive gone through the django 2.2 documentation trying many different things but nothing seems to work
My code is configured as such the template:
<form enctype="multipart/form-data" action="{% url 'order_thanks' %}"
method="post" novalidate>
{% csrf_token %}
{{ form|crispy }}
<input name="Submit" type="submit" class="btn btn-success" value="Git my
food!"></input>
The model:
from django.db import models
from django.forms import ModelForm, Textarea, Select,
CheckboxSelectMultiple, CheckboxSelectMultiple
from django import forms
BURGER_CHOICES = (("AFBB", "Aurion's Famous Beef Burger"), ("AIPB",
"Aurion's Infamous Pork Burger"), ("AULB", "Aurion's Undiscovered Lamb
Burger"), ("POG", "Pureed Otter Giblets"))
BUN_CHOICES = (("WHITE","White Bread"), ("RYE","Rye"), ("TPOODLE",
"Teacup Poodles"), ("AFOSSIL","Ammonite Fossils"))
TOPPING_CHOICES = (("CHEESE", "Cheese"), ("LETTUCE", "Lettuce"),
("TOMATOE", "Tomatoe"), ("ONION", "Onion"), ("WSHAVE", "Wood Shavings"))
SAUCES_CHOICES = (("OZTS", "Our Zesty Barbaque Sauce"), ("SEZBS",
"Someone Elses Zesty Barbaque Sauce"), ("VS", "Varmint Squeezings"))
EXTRAS_CHOICES = (("P", "Pinapple"), ("SG", "Soylent Green"), ("SB",
"Soylent Blue"), ("MWS", "More Wood Shavings"))
class Order(models.Model):
burger = models.CharField(max_length=50,choices=BURGER_CHOICES )
bun = models.CharField(max_length=50, choices=BUN_CHOICES)
toppings = models.CharField(max_length=60, choices=TOPPING_CHOICES)
sauces = models.CharField(max_length=60, choices=SAUCES_CHOICES)
extras = models.CharField(max_length=60, choices=EXTRAS_CHOICES)
# def get_absolute_url(self):
# return reverse('burger', kwargs={'pk': self.pk})
def __str__(self):
return self.burger
def get_absolute_url(self):
return reverse('order-thanks', kwargs={'pk': self.pk})
class OrderForm(ModelForm):
def __init__(self, *args, **kwargs):
super(OrderForm, self).__init__(*args, **kwargs)
self.fields['toppings'].widget = forms.CheckboxSelectMultiple()
for field_name in self.fields:
field = self.fields.get(field_name)
if field and isinstance(field , forms.TypedChoiceField):
field.choices = field.choices[1:]
self.fields['extras'].widget = forms.CheckboxSelectMultiple()
class Meta:
model = Order
fields = ['burger', 'bun', 'toppings', 'sauces', 'extras']
the view:
class OrderView(CreateView, FormView):
template_name = 'order_form.html'
form_class = OrderForm
success_url = 'order/thanks/'
def form_valid(self, form):
form.instance.created_by = self.request.user
return super().form_valid(form)
def get(self, request):
return Response(code=200)
class OrderThanksView(TemplateView):
template_name = 'order_thanks.html'
the urls:
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.HomePage.as_view(),name='home'),
path('about/', views.AboutPage.as_view(),name='about'),
path('order/', views.OrderView.as_view(),name='order'),
path('order/thanks/',
views.OrderThanksView.as_view(),name='order_thanks'),
]
Appologies I dont know how to display the code correctly in the post.
I added some debugging to the code and it turns out that the form is not valid so the redirect doesnt happen?
===============
I got the redirect working by making the multiple choice checkboxes as blank=True and setting the action in the template to "{% url 'order' %}
There seems to be an issue with the form when you select multiple options with eh check-boxes. Any help would be appreciated.
I am new to django and I am trying to create a simple clone version of [pastebin.com][1] that has only one model with name and content. I have created the searchbar in my root template. But what is the actual Class View to filter only the name and show a list of name and content? ` Patebin Assesment Project
<input class="searchfield" id="searchbox" name="q" type="text" placeholder="Search"/>
<input class="searchbutton" type="submit" value="Search"/>
</form>`
As I have already said I am very new with django. Here's My model
from django.db import models
from django.urls import reverse
# Create your models here.
class Post(models.Model):
name = models.CharField(db_index=True, max_length=300, blank=False)
content = models.TextField()
generated_url = models.CharField(db_index=True, max_length=10, blank=False)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("pastebin_app:detail",kwargs={'pk':self.pk})
You need to create a view to handle the search behavior. There is no such generic view, but it's quite easy to create:
class SearchView(TemplateView):
template_name = 'search.html'
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = Post.objects.filter(name__icontains=q)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
return super().get_context_data(results=self.results, **kwargs)
Add your view to your urls.py:
url(r'^search/$', SearchView.as_view(), name='search')
And make sure you set the right action and method attributes to your search form:
<form method="GET" action="{% url 'pastebin_app:search' %}">
I'm super new to django. I am trying to create a clone of pastebin.com which has only one model (Post) with name , content and generated_url.
I am having problem with the searchbar . I dont know how to implement the SearchView into search.html that generate
here's my model
from django.db import models
from django.urls import reverse
# Create your models here.
class Post(models.Model):
name = models.CharField(db_index=True, max_length=300, blank=False)
content = models.TextField()
generated_url = models.CharField(db_index=True, max_length=10, blank=False)
def __str__(self):
return self.name
def get_absolute_url(self):
return reverse("pastebin_app:detail",kwargs={'pk':self.pk})
here's my root.html for the searchbar
<form action="{% url 'pastebin_app:search' %}" method="get" accept-charset="utf-8">
<input name="q" type="text" placeholder="Search">
<input type="submit" value="Search"/>
</form>
and here's the views.py for searchview
class SearchView(ListView):
template_name = 'pastebin_app/search.html'
model = models.Post
def get(self, request, *args, **kwargs):
q = request.GET.get('q', '')
self.results = models.Post.objects.filter(name__icontains=q)
return super().get(request, *args, **kwargs)
def get_context_data(self, **kwargs):
return super().get_context_data(results=self.results, **kwargs)
Can someone please help me creating the show.html template that produce the search result from the SearchView?
You need to checkout django-filter contains a simple api to help you get setup with filtering objects and also how to handle complex filters.
def product_list(request):
f = ProductFilter(request.GET, queryset=Product.objects.all())
return render(request, 'my_app/template.html', {'filter': f})
I'm trying to write a DeleteView for deleting posts without getting displayed a confirmation page.
Del - delete button. How can I delete the object immediately?
urls.py:
urlpatterns = [
# url(r'^$', views.index, name='index'),
url(
r'^feed$',
views.FeedView.as_view(),
name='feed'
),
url(r'^summary(?P<pk>\w{0,50})',
views.SummaryCreate.as_view(),
name='summary'),
url(r'^summary(?P<user_id>\w{0,50})/(?P<pk>\w{0,50})/',
views.SummaryDelete.as_view(),
name='delete_summary'),
url(r'^dashboard$',
permission_required('reed.view_dashboard')
(views.DashboardListView.as_view()),
name='dashboard'),
url(r'^dashboard/(?P<pk>\w{0,50})',
permission_required('reed.view_dashboard')
(views.DashboardUpdate.as_view()),
name='review_summary'),
]
views.py
class SummaryCreate(LoginRequiredMixin, generic.CreateView):
template_name = 'template/summary_list.html'
model = Summary
form_class = AddUrlForm
login_url = '/login_page/login/'
redirect_field_name = 'login_page'
def get_context_data(self, **kwargs):
return dict(
super(SummaryCreate, self).get_context_data(**kwargs),
summary_list=reversed(Summary.objects.filter(user_id=self.kwargs['pk']).reverse())
)
def get_success_url(self):
return reverse('summary', args=(self.request.user.id.hex,))
def form_valid(self, form):
print(self.request.user.id.hex)
url_inst = form.save(commit=False)
keywords_inst = Keywords
article = Article(form.cleaned_data['url'], language='en')
article.download()
article.parse()
title = article.title
print(title)
try:
image = article.top_image
print(image)
except Exception:
image = ''
article.nlp()
try:
keywords = article.keywords
print(keywords)
except Exception:
keywords = 'Sorry,no,keywords,found'
try:
summary = article.summary
print(summary)
except Exception:
summary = 'Sorry, no summmary found'
try:
publish_date = article.publish_date
publish_date = publish_date.date()
print(publish_date)
except Exception:
publish_date = '1900-01-01'
user = User.objects.get(id=self.request.user.id.hex)
url_inst.url=form.cleaned_data['url']
url_inst.image=image
url_inst.title=title
url_inst.summary=summary
url_inst.date=publish_date
url_inst.user_id=user
url_inst.save()
summary = Summary.objects.get(url=form.cleaned_data['url'])
#
for keyword in keywords:
new_keyword = keywords_inst(keyword=keyword, keyword_id=summary)
new_keyword.save()
#
return super(SummaryCreate, self).form_valid(form)
class SummaryDelete(SummaryCreate, generic.DeleteView):
model = Summary
pk_url_kwarg = 'pk'
slug_url_kwarg = 'pk'
def get_success_url(self):
return reverse('summary', args=(self.request.user.id.hex,))
def dispatch(self, request, *args, **kwargs):
return super(SummaryDelete, self).dispatch(request, *args, **kwargs)
template.html:
<form action="{% url 'delete_summary' user.id.hex summary.id.hex %}" method="post">{% csrf_token %}
<h3>
<input type="submit" class="delete" aria-hidden="true" value="X">
{{summary.title}}
</h3>
</form>
I have 2 classes in one template: 1 for displaying all posts and adding new posts and second for deleting, but deleting only redirect me on page, that I provide for DeleteView.
DeleteView:
A view that displays a confirmation page and deletes an existing
object. The given object will only be deleted if the request method is
POST. If this view is fetched via GET, it will display a confirmation
page that should contain a form that POSTs to the same URL.
You need a form element in order to send a POST request.
template.html:
<form id="my_form" method="post" action="{% url 'delete_summary' user.id.hex summary.id.hex %}">
{% csrf_token %}
</form>
Del