View not showing when using modelform - django

I'm trying to display a form, using a model form in django. Everything looks like it's setup properly, and I'm not getting any error. Simply, the form is not showing, although the url is updated...
views.py
from rulz.models import Rulz
class rules_create(CreateView):
model = Rulz
fields=['title', 'content']
models.py
from django.db import models
from django.contrib.auth.models import User
from django.urls import reverse
class Rulz(models.Model):
title = models.CharField(max_length=255)
content = models.TextField()
country = models.CharField(max_length=255,default='France')
city = models.CharField(max_length=255,default='Paris')
player_num = models.IntegerField(default=2)
complexity = models.IntegerField(default=1)
created_on = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(User,on_delete=models.CASCADE,default=1)
def get_absolute_url(self):
return reverse('rulz:rulz_detail',kwargs={'pk':self.pk})
urls.py (in the app)
app_name = 'rulz'
urlpatterns = [
#/rulz/
url(r'^', views.rules_index.as_view(), name='rulz_index'),
url(r'^index/$', views.rules_index.as_view(), name='rulz_index'),
# /rulz/details
url(r'^(?P<pk>[0-9]+)/$',views.rules_detail.as_view(),name='rulz_detail'),
#rulz/create
url(r'^create/',views.rules_create.as_view(),name='rulz_create'),
]
urls.py (root folder)
...
url(r'^rules/',include('rulz.urls')),
...
app/templates/app/rulz_form.html
{% extends 'rulz/Rulz_base.html' %}
{% block body %}
{% load staticfiles %}
{% include 'rulz/form-template.html' %}
{% endblock %}
app/templates/app/form-template.html
{% for field in form %}
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.errors }}</span>
</div>
<div class="validate-input m-b-26" >
<label class="label-input100">{{ field.label_tag }}</label>
<div class="input100">{{ field }}</div>
<div class="col-sm-offset-2 col-sm-10">
<span class="text-danger small">{{ field.help_text }}</span>
</div>
</div>
</div>
and finally the button with the link in my page to access the form :
Go create Rule
I really don't know what I am missing. When I click this button, the url is uploaded to http://127.0.0.1:8000/rules/create/ but the displayed page is exactly the same.
Any clue ?
Thanks

You need to terminate your index regex. At the moment it matches every string the has a start, which of course means every string. Use the $:
url(r'^$', views.rules_index.as_view(), ...
(As an aside, you should avoid having two patterns for the same view.)

In the documentation you can find the list of the attributes needed to correctly rendering your form using CreateView.
So, you need to modify your class based view to look like at least this example:
from rulz.models import Rulz
class rules_create(CreateView):
form_class = YOUR_FORM # The form that will be used with this class
model = Rulz
fields=['title', 'content']
success_url = 'YOUR_SUCCESS_URL' # If success redirect to this URL

Related

Django: objects are not showing at index page

This is my first project with Django and I got a problem. In the backend I created news, but I have an issue displaying the news on the frontpage. Models should be fine since I can create news into the admin panel. But I can't figure out where is my mistake.
I have app 'pages'>views.py
from django.shortcuts import render, redirect, get_object_or_404
from mainnews.models import Mainnews
# Create your views here.
def home_view(request):
main = Mainnews.objects.all()
context = {
'main' : main
}
return render(request, 'index.html', context)
root>urls.py
from pages.views import home_view
urlpatterns = [
path('admin/', admin.site.urls),
path('', home_view, name = 'home'),
]
and app mainnews>views.py
from django.shortcuts import render, get_object_or_404
from .models import Mainnews
# Create your views here.
def index(request):
main = Mainnews.objects.all()
context = {
'main' : main
}
return render(request, 'index.html', context)
and the template mainnewsandevents.html that extends to index
{% block content %}
<!-- Section 2 News and Events -->
<div id="news-container">
<div class="jumbo-news">
<img id = 'jumboImgUrl' class='jumbo-img' src="{{ main.image.url }}">
<h2 id = 'jumboTitle' class='jumbo-title'>{{ main.title }}</h2>
<h4 id = 'jumboDescription' class='jumbo-parag'>{{ main.description }}</h4>
</div>
{% endblock %}
Fix it like this:
def home_view(request):
main = Mainnews.objects.first()
# or main = Mainnews.objects.last()
# other code
or if you need to show all objects on your template use something like it:
{% block content %}
<!-- Section 2 News and Events -->
<div id="news-container">
<div class="jumbo-news">
{% for article in main %}
<img id = 'jumboImgUrl' class='jumbo-img' src="{{ main.image.url }}">
<h2 id = 'jumboTitle' class='jumbo-title'>{{ main.title }}</h2>
<h4 id = 'jumboDescription' class='jumbo-parag'>{{ main.description }}</h4>
{% endfor %}
</div>
{% endblock %}
Depends on your needs.
Also you shouldn't use not obvious names for variables so you shall use main_news instead of main.
main is an array of objects right so you need a for loop to get every object
{% block content %}
<!-- Section 2 News and Events -->
<div id="news-container">
<div class="jumbo-news">
{% for obj in main %}
<img id = 'jumboImgUrl' class='jumbo-img' src={{ obj.image.url }}>
<h2 id = 'jumboTitle' class='jumbo-title'>{{ obj.title }}</h2>
<h4 id = 'jumboDescription' class='jumbo-parag'>{{ obj.description }}</h4>
{% endfor %}
</div>
{% endblock %}

DJANGO: How to access data from ListView and DetailView on the same template?

I am trying to create a webpage which has two parts.
An index list of all items (that persists throughout)
Detail of the selected index item
I created a LIST VIEW and a DETAIL VIEW for the same but the problem is both views cannot be called on the same template.
I tried to list all the items in 'reports_list.html' and then inherit this template to 'report_detail.html' to see if the index list stays but it doesn't.
Is there a way to accomplish this?
CODE:
views.py
from django.shortcuts import render
from django.views.generic import TemplateView, DetailView, ListView
from .models import Reports
from django.utils import timezone
class index(TemplateView):
template_name = 'reports_list.html'
class ReportsListView(ListView):
model = Reports
def get_queryset(self):
return Reports.objects.filter(create_date__lte=timezone.now()).order_by('-create_date')
class Detail(DetailView):
model = Reports
reports_list.html
<ul class="index-list">
{% for report in reports_list %}
<li data-id= {{ report.pk }}>
<a class="index-link" href="{% url 'reports:reports_detail' pk=report.pk %}">
<span class="index-name">{{report.title}}</span>
</a>
</li>
{% endfor %}
</ul>
report_detail.html
{% extends './reports_list.html' %}
{% block contentblock %}
<h1>THIS IS DETAIL VIEW</h1>
<div class="read-header">
<div class="read-title">
{{ reports.title }}
</div>
</div>
<div class="read-subtitle">
{{ reports.subtitle }}
</div>
<div class="read-content">
{{reports.content}}
</div>
{% endblock %}
All you have to do is pass additional context data to DetailView for the list to see since you are extending the template here. Docs
class Detail(DetailView):
model = Reports
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
# Add in the reports list to context
context['reports_list'] = Reports.objects.filter(create_date__lte=timezone.now()).order_by('-create_date')
return context

Django No Reverse Match Error

I've been working on this error for the better part of a week and this is the error I keep receiving:
>
NoReverseMatch at /practice/practice/2/saleinfoedit/
Reverse for 'car_detail' with keyword arguments '{'pk': ''}' not found. 1 pattern(s) tried: ['practice/practice/(?P<pk>\\d)$']
I've simplified the code to what are the relevant parts of the error, I think. The idea is to have a list page of cars and when you click on the car link you can edit the Sale History of the vehicle. Eventually I'll setup formsets for this part, but babysteps. Here's the relevant code:
models.py
class Car(models.Model):
car_name = models.CharField(max_length=200)
color = models.CharField(max_length=200)
age = models.CharField(max_length=200)
def get_absolute_url(self):
return reverse('practice:car_detail',kwargs={'pk':self.pk})
def __str__(self):
return '%s' %(self.car_name)
class SaleInfo(models.Model):
car_name = models.ForeignKey(Car, on_delete=models.CASCADE,)
price = models.CharField(max_length=100)
date = models.CharField(max_length=100)
comments = models.CharField(max_length=200)
def __str__(self):
return '%s' %(self.car_name)
def get_absolute_url(self):
return reverse('practice:car_detail',kwargs={'pk':self.pk})
views.py
class IndexView(generic.ListView):
template_name = 'practice/carlist.html'
context_object_name = 'latest_car_list'
def get_queryset(self):
return Car.objects.all()
class DetailView(generic.DetailView):
model = Car
form_class = CarForm
template_name = 'practice/car_detail.html'
class UpdateView(generic.UpdateView):
model = Car
form_class = CarFormEdit
class SaleInfoUpdateView(generic.UpdateView):
model = SaleInfo
form_class = SaleInfoFormEdit
template_name = 'practice/saleinfo_form.html'
urls.py
app_name = 'practice'
urlpatterns = [
url(r'^$', views.IndexView.as_view(), name='index'), # shows lists of Cars via Car Name
url(r'^practice/(?P<pk>\d)$', views.DetailView.as_view(), name='car_detail'),
url(r'^practice/(?P<pk>\d)/edit/$', views.UpdateView.as_view(), name='car_edit'),
url(r'^practice/(?P<pk>\d)/saleinfoedit/$', views.SaleInfoUpdateView.as_view(), name='saleinfo_edit'),
]
car_detail.html
{% extends 'practice/car_base.html' %}
{% block post_content %}
<div class="col-md-8">
<a class='btn btn-primary' href="{% url 'practice:car_edit' pk=car.pk %}">
<span class='glyphicon glyphicon-pencil'></span>
</a>
<p>{{ car.car_name|safe }}</p>
<p>{{ car.color|safe }} {{ car.age|safe }} </p>
<a class='btn btn-primary' href="{% url 'practice:saleinfo_edit' pk=car.pk %}">
<span class='glyphicon glyphicon-pencil'> SaleInfo</span>
</a>
</div>
{% endblock %}
saleinfo_form.html
{% extends 'practice/car_base.html' %}
{% block post_content %}
{% load bootstrap3 %}
<form class="" action="" method="post">
{% csrf_token %}
{% bootstrap_form form %}
<!-- {{form.as_p}} -->
<input type="submit" name="" value="Update">
</form>
{% endblock %}
I can post my templates too if necessary. I'm sure it's something simple I keep looking past, but after a few days I'm lost.
According to the error message, the parameter pk you have given to the {% url %} tag is empty:
...with keyword arguments '{'pk': ''}'
There are two common reasons for that:
You have a typo in your variable name in your template.
You are creating a new object, so it doesn't have an ID/PK yet.
Your templates look fine though, so here is how I would debug it:
Remove {% url %} tags one after the other until you find the actual culprit.
Print out the variable you pass as keyword argument pk.
One more thing: \d matches exactly one digit, so your URL patterns will stop working once you have more than 9 cars. You have to add a + to match one or more digits:
url(r'^practice/(?P<pk>\d+)/edit/$', views.UpdateView.as_view(), name='car_edit'),
Also, like #wencakisa remarked, URLs in Django usually end with a slash, but that isn't mandatory.
Edit: I just noticed two more things:
your SaleInfo.get_absolute_url method uses practice:car_detail. Shouldn't that be saleinfo_edit?
in the car_detail.html template, you use {% url 'practice:saleinfo_edit' pk=car.pk %}. That won't work. If there is only one SaleInfo per car, use a OneToOneField instead of a ForeignKey in your model. Then you can do something like:
{% if car.sale_info %}
{% url 'practice:saleinfo_edit' pk=car.sale_info.pk %}
{% endif %}

Models inherit fields from other models in Django

I have the following models. I am trying to get the newlistitem model to inherit the same image from the above, if that makes sense. I see that I passed through user as a parameter when calling listitem.user and it works fine, but can't seem to grab the picture of the related object.
HTML Render
I am returning both objects to the form and call
{% for item in listitems %}
<div id = "indivlistitem">
<b>{{item.list_name|title}}</b>
<li><img src="/media/{{ item.list_picture }}"/></li>
<li>{{item|title}}</li>
</div>
{% endfor %}
#MODELS
from django.db import models
from django.contrib.auth.models import User
class newlist(models.Model):
user = models.ForeignKey(User)
list_name = models.CharField(max_length = 100)
picture = models.ImageField(upload_to='profiles/')
def __str__(self):
return self.list_name
class newlistitem(models.Model):
user = models.ForeignKey(User)
list_name = models.ForeignKey(newlist)
list_item = models.CharField(max_length = 200)
list_picture = models.ImageField(newlist.picture)
def __str__(self):
return self.list_item
First things first, list_picture = models.ImageField(newlist.picture)
is not going to work. However, it did provide some insight into what you're trying to do.
Since you already have a foreign key to a list in the newlistitem model (your list_name field), you can access the picture that it's linked to by traversing the foreign key, as such.
You'll note that I've also used the url property that all ImageFields contain, to automatically populate the URL of the picture:
{% for item in listitems %}
<div id = "indivlistitem">
<b>{{item.list_name|title}}</b>
<li><img src="{{ item.list_name.picture.url }}"/></li>
<li>{{item|title}}</li>
</div>
{% endfor %}
UPDATE
Some of the pictures that you are trying to access are blank, so you will need to validate that there is an image associated with each entry.
{% for item in listitems %}
<div id = "indivlistitem">
<b>{{item.list_name|title}}</b>
{% if item.list_name.picture %}
<li><img src="{{ item.list_name.picture.url }}"/></li>
{% endif %}
<li>{{item|title}}</li>
</div>
{% endfor %}

Django Error After Changing/Reverting Views

I was changing some views earlier related to some geolocation (that failed) and upon restoring the previous views, I'm receiving this error:
TemplateSyntaxError at /report/all/
Caught NoReverseMatch while rendering: Reverse for 'profiles_profile_detail' with arguments '('',)' and keyword arguments '{}' not found.
What's odd is that the views I altered and restored had nothing to do with this view or template. The urls.py file was not touched at all. All other pages in the application are displaying normally. I can't figure out what the problem might be.
Views:
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import render_to_response, get_object_or_404, redirect
from django.template import RequestContext
from django.core.urlresolvers import reverse
from myapp.report.models import Story, UserProfile
from myapp.report.forms import ProfileForm, StoryForm
from django.contrib.auth.decorators import login_required
from django.contrib.gis.utils import GeoIP
def all_stories(request):
if not request.user.is_authenticated():
return redirect("django.contrib.auth.views.login")
all_stories = Story.objects.all().order_by("-date")
return render_to_response("report/storyline.html",
{'stories': all_stories},
context_instance=RequestContext(request))
def story_detail(request, story_id):
story = get_object_or_404(Story, id=story_id)
return render_to_response('report/detail.html',
{'story': story},
context_instance=RequestContext(request))
#login_required
def submit_story(request):
if request.method =="POST":
story_form = StoryForm(request.POST, request.FILES)
if story_form.is_valid():
new_story = story_form.save(commit=False)
new_story.author = request.user
new_story.save()
return HttpResponseRedirect("/report/all/")
else: # GET request
story_form = StoryForm()
return render_to_response("report/report.html", {'form': story_form}, context_instance=RequestContext(request))
Forms (changed but restored; appear to be working):
from django import forms
from stentorian.report.models import UserProfile, Story
from django.contrib.gis.utils import GeoIP
class ProfileForm(forms.ModelForm):
class Meta:
model = UserProfile
class StoryForm(forms.ModelForm):
class Meta:
model = Story
exclude = ('author',)
Template:
{% extends 'base.html' %}
{% block page_title %}Stentorian{% endblock %}
{% block headline %}Stentorian Storyline{% endblock %}
{% block content %}
<div class="row">
<div class="span12">
<h2>Welcome {{ user.username }}</h2>
<div class="accordion" id="story_accordion">
{% for story in stories %}
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle story-header" data-toggle="collapse" data-parent="#story_accordion" href="#story_{{ story.id }}">
{{ story.title }} - {{ story.author.username }} - {{ story.date }}
</a>
</div>
<div id="story_{{ story.id }}" class="accordion-body collapse{% if forloop.counter0 == 0 %} in{% endif %}">
<div class="accordion-inner">
<!-- <h2>{{story.title}}</h2>-->
<span>{{story.author}} </span><br>
<span>{{story.topic}}</span><br>
<span>{{story.zip_code}}</span><br>
<span>{{story.date}}</span><br>
<p>{{story.copy}}</p>
</div>
</div>
</div>
<br>
{% endfor %}
</div>
</div>
</div>
{% endblock content %}
The error is coming up on the line:
{% for story in stories %}
If anyone can provide an idea of why this is happening, it would be most appreciated. Again, the url wasn't changed, which seems to be the chief reason for this error.
Seems like u r not getting user.username
Try with this.
<h2>Welcome {{ request.user.username }}</h2>