Django: generic.UpdateView with form_class won't render form - python

I'm having a really confusing issue with some views in Django. I created Update and Create views, both using the generic versions, both using the same template. They worked perfectly...until I added a custom modelForm to exclude a field. Now, the Create view still works correctly, but the Update view won't render a form at all.
Form:
class member_form(ModelForm):
class Meta:
model=member
exclude=('created_by',)
Views:
class member_detail(generic.UpdateView):
form_class=member_form
model=member
template_name_suffix='_detail'
class member_create(generic.CreateView):
form_class=member_form
model=member
template_name_suffix='_detail'
Urls (main):
url(r'^members/',include(members.urls',namespace=members),name='members_list'),
Urls (app):
url(r'^$',login_required(views.member_list.as_view()),name='index'),
url(r'^(?P<pk>\d+)/$',login_required(views.member_detail.as_view(success_url=".")),name='detail'),
url(r'^new/$',permission_required('members.add_member')(views.member_create.as_view(success_url='/members/')),name='create'),
This worked perfectly for both views until I added the form_class. Now, member_create still works perfectly, but member_detail shows nothing for {{ form.as_table }}. When I switch it to just {{ form }} in that template, I get this for member_detail:
<members.views.member_form object at 0x7f7de3f20d50>
What's going on here? Any ideas? Thanks!

The problem was a stupid naming mistake on my part, on the production code, which I found while trying to redact new sections to add to the question; the _create and _form objects in my question were both named _form in production.

Related

Template password_reset_form.html does not overwrite the django admin template

I am looking to rewrite the template present in the urls of django.contrib.auth.urls, among them, accounts /password_reset/[name = 'password_reset'], however I am not succeeding in replacing the django admin template for this url, with my template My template is in registration/password_reset_form.html, as described in the documentation, but not working.
I think I understand your problem and I believe it is identical to this one: How to override my template instead of django admin panel for reset password?
Make sure your application name is the first one in the list of INSTALLED_APPS in settings.py. That solved it for me.
Are you using CBV (class based views)? In views.py or in urls.py set template_name.
example:
path('question_directory/', views.UpdateDirectry.as_view(template_name='accounts/profile_form.html'), name='question_directory')
or
class UpdateDirectry(generic.edit.FormView):
model = Question
template_name = 'accounts/editable_directory.html'

Django Templates can not access to context

I checked all the questions and answers in this site, but could not find a solution. I am new in Django, trying to develop a storage model and stucked already in the ListView.
part of my view.py:
from django.shortcuts import render, redirect
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic.list import ListView
from django.views.generic.detail import DetailView
from Storage.models import Storage
from django.http import HttpResponse
class StorageListView(LoginRequiredMixin, ListView):
model = Storage
print(Storage.objects.order_by('-barcode'))
template_name = 'Storage/Storagelist.html'
def get_queryset(self):
return Storage.objects.order_by('-barcode')
I add print statement to check whether I reach the model and
everyting seems normal:
<QuerySet [<Storage: 123>, <Storage: 122>, <Storage: 121>]>
However, I can not reach the context from the template file 'Storagelist.html':
<h3>trial</h3>
{% if storage_list %} <h3>trial</h3> {% endif %}
Just to check access via url configurations, I added 'trial' at the beginning of the template and it also seems normal. I also tried to use context_object_name, but did not help either. Somehow, I can not reach to ListView context data from the template.
My versions of applications are as follows:
Django 2.0.3
Python 3.6.1
Can somebody please help me?
In a ListView I believe the objects will populate into the template as object_list. You might consider using this method to make the template context variable human readable (and also match what you are expecting). In other words, try adding context_object_name = storage_list to your view.

Why is the get_absolute_url() defined in the models.py?

I am trying to redo my app views with a Class Based Views(CBV) and stumbled across this function get_absolute_url() being defined in the models.py, generic editing views
I have created models and have never used this function before. Is this specific to CBVs?
It's not specific to CBV, you can use it anywhere in your application. It makes it much easier to get the url for a model instance without having to mess around with url resolving. Also it is much easier to get the definitive url for your object in a template when you can call get_absolute_url on the object itself. For example, if you are looping through a list of objects:
{% for post in blog_posts %}
read post
{% endfor %}
That said, there's nothing stopping you using the method in your view either:
post = BlogPost.objects.get(...)
url = post.get_absolute_url()
There's also is nothing at all special about the method though. You can write your own get_foo_url() if you like instead. For example, I wrote a blog post about a get_admin_url, a method to allow you to get the Django admin url to an object:
class Book(models.Model):
...
def get_admin_url(self):
content_type = ContentType \
.objects \
.get_for_model(self.__class__)
return reverse("admin:%s_%s_change" % (
content_type.app_label,
content_type.model),
args=(self.id,))
# {{ book.get_admin_url }}

How to avoid hardcoded template name in a django app, integrated with django-cms?

I have a custom Contact Form App, and I want to integrate it with django-cms. From what I understand I have to register the app with django-cms, and then in my views I have to return a RequestContext instance instead of a regular context instance. So in my views.py, I have
return render_to_response('my_template.html',
{'form': form},
context_instance=RequestContext(request))
I don't know if I'm missing something here, but my issue here is that I don't want to hardcode the template name my_template.html. Instead, I want the template to be the same one I put when adding a new page, so my question is, is there a way to get the template from the django-cms page thats hosting the app or do I have to hardcode the template to be used?
If your apphook is a single view mounted on /, you can just use {% extends request.current_page.get_template %}, however this does not work on subpages in your app.
For that you would need to reverse the root view of your app, use cms.utils.page_resolver.get_page_from_request with the use_path argument to get the page, then call get_template on the page and extend that.

How do I add data to an existing model in Django?

Currently, I am writing up a bit of a product-based CMS as my first project.
Here is my question. How can I add additional data (products) to my Product model?
I have added '/admin/products/add' to my urls.py, but I don't really know where to go from there. How would i build both my view and my template? Please keep in mind that I don't really know all that much Python, and i am very new to Django
How can I do this all without using this existing django admin interface.
You will want to wire your URL to the Django create_object generic view, and pass it either "model" (the model you want to create) or "form_class" (a customized ModelForm class). There are a number of other arguments you can also pass to override default behaviors.
Sample URLconf for the simplest case:
from django.conf.urls.defaults import *
from django.views.generic.create_update import create_object
from my_products_app.models import Product
urlpatterns = patterns('',
url(r'^admin/products/add/$', create_object, {'model': Product}))
Your template will get the context variable "form", which you just need to wrap in a <form> tag and add a submit button. The simplest working template (by default should go in "my_products_app/product_form.html"):
<form action="." method="POST">
{{ form }}
<input type="submit" name="submit" value="add">
</form>
Note that your Product model must have a get_absolute_url method, or else you must pass in the post_save_redirect parameter to the view. Otherwise it won't know where to redirect to after save.
This topic is covered in Django tutorials.
Follow the Django tutorial for setting up the "admin" part of an application. This will allow you to modify your database.
Django Admin Setup
Alternatively, you can just connect directly to the database using the standard tools for whatever database type you are using.

Categories

Resources