I am really having hard time to understand ways to dispatch arguments and keword arguments to Django urls. Following is the case study:
I've a view using generic base view:
class CartView(View):
def get(self, request, *args, **kwargs):
item = request.GET.get('item')
qty = request.GET.get('qty')
print item, qty
return HttpResponseRedirect('/')
With above view I was able to work with aurguments in url like "localhost:8000/cart/?item=4&qty=200" and it prints the item with quantity in terminal.
As soon I've made changes in code like:
from carts.models import Cart, CartItem
from products.models import Variation
class CartView(View):
def get(self, request, *args, **kwargs):
item_id = request.GET.get('item')
if item_id:
item_instance = get_object_or_404(Variation, id=item_id)
qty = request.GET.get('qty')
cart = Cart.objects.all()[0]
cart_item = CartItem.objects.get_or_create(cart=cart, item=item_instance)[0]
cart_item.quantity = qty
cart_item.save()
print cart_item
return HttpResponseRedirect('/')
With same way passing arguments like "localhost:8000/cart/?item=4&qty=200" it shows me the error:
404 Page Not Found No Variation matches the given query.
urls.py
urlpatterns = [
url(r'^home/$', 'newsletter.views.home', name='home'),
url(r'^contact/$', 'newsletter.views.contact', name='contact'),
url(r'^about/$', 'project.views.about', name='about'),
url(r'^admin/', include(admin.site.urls)),
url(r'^accounts/', include('registration.backends.default.urls')),
url(r'^cart/$', CartView.as_view(), name='cart'),
url(r'^', include('products.urls')),
url(r'^categories/', include('products.urls_categories')),
404 Page Not Found
No Variation matches the given query.
This message comes from your line:
item_instance = get_object_or_404(Variation, id=item_id)
And means that you have no Variation object matching the given id.
Related
The problem is I can't type http://localhost:8000/1 to see spesific ViedoLibrary in my database. Can anyone help me to find the solution?
urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('', views.index, name='index'),
path('main/', views.main, name='main'),
path('create_view/', views.create_view, name='create_view'),
path('list_view/', views.list_view, name='list_view'),
path('<id>', views.detail_view),
]
views.py
def detail_view(request, id):
context = {}
context['data'] = VideoLibrary.objects.get(shop_id=id)
return render(request, 'app/detail_view.html', context)
models.py
class VideoLibrary(models.Model):
shop_id = models.AutoField(primary_key=True, unique=True)
shop_name = models.CharField(max_length=264)
adress = models.TextField(max_length=264, default='')
Also if I type id=id in views.py the next error pops up : Cannot resolve keyword 'id' into field. Choices are: adress, attendance, equipment, films, genre, income, shop_id, shop_name, staff.
This are all my classes in models.py but there are also adress, shop_id and shop_name that are from specific model
Updated.
You have overriden the id field of your model that is why it won't work with id=id since the latter is actually shop_id. Change it accordingly and it should work.
The id error is telling you that you cannot use id as a field and giving you the list of available model fields you can use for filtering. See this answer for more details. Error: Cannot resolve keyword 'id' into field
Update 2
Your views:
from . models import VideoLibrary
def videoLibrary(request):
context = {}
context['data'] = VideoLibrary.objects.all()
return render(request, 'appname/list_view.html', context)
def detail_view(request, id):
context = {}
context['data'] = VideoLibrary.objects.get(shop_id=id)
return render(request, 'appname/detail_view.html', context)
Your urls.py:
urlpatterns = [
path('admin/', admin.site.urls),
path('videos/', views.videoLibrary, name='list_view'),
path('videos/<int:id>', views.detail_view),
]
Now, if you enter http://127.0.0.1:8000/videos this gives you the list view. And http://127.0.0.1:8000/videos/1 gives you VideoLibrary with id 1.
I keep getting this error ('function' object is not iterable) after having added a new def function in my .views file, any thoughts on what the problem could be?
The goal with this is to filter querysets with checkboxes.
Here's my views.py function:
def FilterView(request):
qs = Product.objects.all()
ptag = request.GET.get('ptag')
if ptag == 'on':
qs = qs.filter(ptag='')
qs = filter(request)
context = {
'queryset': qs
}
return render(request, "partials/search_form.html", context)
And in my urls:
from search.views import HomeView, FilterView
urlpatterns = [
url(r'^$', HomeView.as_view(), FilterView),
]
Thanks so much!
Your code doesn't make sense. You are passing both your HomeView and your FilterView to a single url(), and you are running the builtin filter function on a request object? Here should be a working example, minus the unexplained filter():
urls.py
from search.views import HomeView, FilterView
urlpatterns = [
...
url(r'^$', FilterView, name='filter'),
...
]
views.py
def FilterView(request):
ptag = request.GET.get('ptag', '')
qs = Product.objects.all() if ptag != 'on' else Product.objects.filter(ptag='')
#qs = filter(request) # What is this even trying to do?
context = {
'queryset': qs
}
return render(request, "partials/search_form.html", context)
You are passing in both homeview and filterview. You need to choose one.
in urls.py
change
url(r'^$', HomeView.as_view(), FilterView)
to
url(r'^$', Filterview)
I've got a DeleteView I use for removing objects from a model. It is launched via a button in a table. It works fine.
class DeleteAssignment(DeleteView):
model = Assignment
success_url = reverse_lazy('company')
I just want to have it return to it's parent view on success. I currently have it redirecting to the parent's parent (company), as this view doesn't require a variable. This would be simple, but the parent view requires a variable farm_id to render, this is captured from the url like "/farm/18"
url(r'^farm/(?P<farm_id>.+)', views.farm, name='farm'),
I've solved this with forms on the page by having them redirect to the view farm with the variable farm_id.
return redirect(farm, farm_id=farm_id)
How could I do this with the success_url for my DeleteView?
Example for nickie:
views.py
#login_required
def farm(request, farm_id=None):
user = request.user
company_id = user.profile.company_id
farm_id = farm_id
farm_filter = Farm.objects.filter(farm=farm_id)
farm_current = farm_filter[0]
# farm_company =
serial_filter = Sensor.objects.filter(assignment__farm__company_id__isnull=True)
assignment_filter = Assignment.objects.filter(farm=farm_id)
farm_instance = Farm.objects.get(farm=farm_filter[0].farm)
update_farm_form = UpdateFarmForm(instance=farm_instance)
assign_sensor_form = AssignmentForm()
if request.method == 'POST' and 'updatefarm' in request.POST:
update_farm_form = UpdateFarmForm(request.POST, instance=farm_instance)
if update_farm_form.is_valid():
update_farm_form.save()
return redirect(farm, farm_id=farm_id)
else:
if request.method == "POST" and 'assignsensor' in request.POST:
assign_sensor_form = AssignmentForm(request.POST)
if assign_sensor_form.is_valid():
assignment = assign_sensor_form.save()
if user.is_staff is True:
assignment.company_id = farm_filter[0].company_id
else:
assignment.company_id = user.profile.company_id
assignment.save()
return redirect(farm, farm_id=farm_id)
else:
assign_sensor_form = AssignmentForm(request.POST)
return render(request, 'users/farm_template.html', {'company_id': company_id, 'farm_filter': farm_filter, 'farm_current': farm_current, 'serial_filter': serial_filter, 'assignment_filter': assignment_filter, 'update_farm_form': update_farm_form, 'assign_sensor_form': assign_sensor_form})
urls.py
from django.conf.urls import url, include
from django.contrib.auth import views as auth_views
from apps.dashboard import views
from apps.dashboard.views import DeleteAssignment, DeleteFarm
urlpatterns = [
url(r'^company/', views.company_view, name='company'),
# url(r'^test/', views.test),
# url(r'^test2/', views.test2, name='test2'),
# url(r'^farms/', views.add_farms),
url(r'^manual-signup/', views.signup_manual),
url(r'^signup/(?P<company_id>.+)', views.signup_company),
url(r'^settings/', views.update_profile),
url(r'^create-company/', views.create_company),
url(r'^create-sensor/', views.create_sensor),
url(r'^assign-sensor/', views.assign_sensor),
url(r'^login/$', auth_views.login, {'template_name': 'login.html'}, name='login'),
url(r'^logout/$', auth_views.logout, {'next_page': '/login'}, name='logout'),
url(r'^$', views.main),
# url(r'^company/(?P<company_id>.+)/farm/(?P<farm_id>.+)', views.farm),
url(r'^farm/(?P<farm_id>.+)', views.farm, name='farm'),
url(r'^unit/(?P<sensor_id>.+)', views.unit),
# url(r'^company/(?P<company_id>.+)', views.company),
url(r'^download/', views.download),
# url(r'^export/xls/$', views.export_users_xls),
url(r'^live/', views.live),
url(r'^data/', views.data),
url(r'^debug/', views.debug),
url(r'^delete-assignment/(?P<pk>\d+)/$', DeleteAssignment.as_view(), name='delete-assignment', ),
url(r'^delete-farm/(?P<pk>\d+)/$', DeleteFarm.as_view(), name='delete-farm', ),
url(r'^', include('django.contrib.auth.urls'))
]
This is view redirects to itself upon successful form submission. This reloads tables based on the user submission without having to deal with js for now.
The farm_id in return redirect(farm, farm_id=farm_id) is captured from the url, via the appropriate line in urls.py url(r'^farm/(?P<farm_id>.+)', views.farm, name='farm'),
This is all I want to do with the delete view, instead of the success url simply being a view, a view with a variable like I did above.
Yes, you can do this with success_url in this way:
class DeleteAssignment(DeleteView):
. . . . .
. . . . .
. . . . .
def get_success_url(self):
# if you are passing 'pk' from 'urls' to 'DeleteView' for company
# capture that 'pk' as companyid and pass it to 'reverse_lazy()' function
companyid=self.kwargs['pk']
return reverse_lazy('company', kwargs={'pk': companyid})
This should work perfectly.
As Nickie suggested in the comments: https://docs.djangoproject.com/en/1.11/ref/class-based-views/mixins-editing/#django.views.generic.edit.DeletionMixin.success_url
Solved this with success_url = "/farm/{farm_id}"
The following works:
reverse_lazy('name_of_your_view', kwargs={'key': value})
Not documented either in the man page or in docstring, was suggested by AI.
I am doing a tutorial regarding django and I have two errors:
When I try to create a plant that plant is saved in the data but I get this error:
Exception Type: DisallowedRedirect
Exception Value: Unsafe redirect to URL with protocol 'data'
when I try to edit then I get this error
Exception Type: NoReverseMatch
Exception Value: Reverse for 'plants' with arguments '()' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Looking forward to find my mistake.
views.py:
def create_plant(request):
if not request.user.is_authenticated():
return render(request, 'data/login.html')
elif request.method == "POST":
form = PlantForm(request.POST)
if form.is_valid():
plant = form.save(commit=False)
plant.save()
return redirect('data:plants.html', slug = plant.slug)
else:
form=PlantForm()
template = 'data/create_plant.html'
context = {'form': form, }
return render(request, template, context)
def edit_plant(request, slug):
plant = get_object_or_404(Plant, slug=slug)
if request.method=="POST":
form = PlantForm(request.POST, instance=plant)
if form.is_valid():
plant = form.save(commit=False)
plant.save()
return redirect('data:plants')
else:
form = PlantForm(instance=plant)
template = 'data/create_plant.html'
context = {'form': form}
return render(request, template, context)
urls.py:
from django.conf.urls import url
from . import views
app_name = 'data'
urlpatterns = [
url(r'^$', views.home, name='home'),
url(r'^plants/$', views.index, name='index'),
url(r'^create_plant/$', views.create_plant, name='create_plant'),
url(r'^logout_user/$', views.logout_user, name='logout_user'),
url(r'^login_user/$', views.login_user, name='login_user'),
url(r'^register/$', views.register, name='register'),
url(r'^plants/(?P<slug>[-\w]+)/$',views.detail, name='detail'),
url(r'^plants/(?P<slug>[-\w]+)/edit/$', views.edit_plant, name='edit_plant'),
url(r'^(?P<plant_id>[0-9]+)/delete_plant/$', views.delete_plant, name='delete_plant'),]
The problem was at return redirect('data:plants.html', slug = plant.slug) it should be return redirect('data:index') – George 3 hours ago
I'm trying to get the absolute url for particular items in my model.
models.py
class BannerAds(models.Model):
name = models.CharField(max_length=256)
phone = models.CharField(max_length=20)
def __unicode__(self):
return self.name
#permalink
def get_absolute_url(self):
from django.core.urlresolvers import reverse
return reverse('index', args=[str(self.name)])
views.py
def banners(request):
context = RequestContext(request)
all_banners = BannerAds.objects.all()
content_dict = {'banners': all_banners,}
return render_to_response('templates/banner.html', content_dict, context)
def index(request):
context = RequestContext(request)
banner_list = BannerAds.objects.all()
city_list = Cities.objects.order_by('name')
offer_list = NewOffers.objects.order_by('offer_add_date')[:5]
context_dic = {'banner_list': banner_list,
'cities': city_list,
'offers': offer_list,
}
return render_to_response('templates/index.html', context_dic, context)
urls.py
urlpatterns = patterns('',
url(r'^admin/', include(admin.site.urls)),
url(r'^$', views.index, name='index'),
url(r'^advertise/', views.advertise, name='advertise'),
url(r'^about/', views.about, name='about'),
url(r'^listing/', views.listing, name='listing'),
url(r'^search/', views.search, name='search'),
url(r'^add/', views.add_listing, name='add'),
url(r'^offers/', views.offers, name='offer'),
url(r'^add_listing/$', views.add_listing, name='add_listing'),
url(r'^listing/(?P<listing_url>\w+)/$', views.listing, name='category'),
url(r'^testimonial/', views.testimonials, name='testimonial'),
url(r'^add_testimonial', views.add_testimonial, name='add_testimonial'),
url(r'^banner', views.banners, name='banners'),
)
I've entered test data as name=test, phone = testing.
When I try to open the page, it gives me a No Reverse Match at / error along with a
Reverse for '' with arguments '('Testing',)' and keyword arguments '{}' not found. 0 pattern(s) tried: []
Any idea what I'm missing? I'm pretty new to Django development so solutions with code examples would help me a lot.
Change the view banners to as you are passing args.
def banners(request, name):
context = RequestContext(request)
all_banners = BannerAds.objects.all()
content_dict = {'banners': all_banners,}
return render_to_response('templates/banner.html', content_dict, context)
Also, make sure you have made an entry in urls.py with name="banners"
Don't use both #permalink and reverse(). They do the same thing. Either drop the decorator, or just return the tuple of (view_name, args).
In fact, the documentation says that permalink is deprecated, so the best thing is just to remove it.
The url url(r'^$', views.index, name='index') does not accept any parameter so why are you passing args here reverse('index', args=[str(self.name)])?
If you want a detail view and wants the name to be optional parameter for index then you can do:
url(r'^(?:(?P<name>.+?)/)?$', views.index, name='index')
Also change the index view to this:
def index(request, name=None):
context = RequestContext(request)
banner_list = BannerAds.objects.all()
# now if name parameter is not None you may want to just pick single object
banner_obj = None
if name:
banner_obj = BannerAds.objects.get(name__exact=name)
city_list = Cities.objects.order_by('name')
offer_list = NewOffers.objects.order_by('offer_add_date')[:5]
context_dic = {'banner_list': banner_list,
'cities': city_list,
'offers': offer_list,
'banner_obj': banner_obj,
}
return render_to_response('templates/index.html', context_dic, context)
Or have a separate view which will serve for the detail of BannerAds.