Displaying model data in Django using for loop - python

Im attempting to display all the course Names in my Course Model,
{% for course in object_list%}
<li>{{ course.courseName}} </li>
{% endfor %}
</ol>
Heres a snippet from the HTML page Im trying to display them in.
here's my models.py
# Create your models here.
SEMESTER_CHOICES = (
("SPR 21", "SPR 21"),
("FA 21", "FA 21"),
("SPR 22", "SPR 22"),
("FA 22", "FA 22"),
("SPR 23", "SPR 23"),
("FA 23", "FA 23"),
("SPR 24 ", "SPR 24"),
("FA 24", "FA 24"),
)
PROGRAM_CHOICES = (
("Architectural Science","Architectural Science"),
("Civil Engineering","Civil Engineering"),
("Computer Information Technology","Computer Information Technology"),
("Computer Science","Computer Science"),
("Construction Management","Construction Management"),
("Electrical Engineering","Electrical Engineering"),
("Engineering Technology Management","Engineering Technology Management"),
("Manufacturing Engineering","Manufacturing Engineering"),
("Mechanical_Engineering","Mechanical_Engineering")
)
# declaring a Student Model
class AddCourse(models.Model):
program = models.CharField(
max_length = 20,
choices = PROGRAM_CHOICES,
default = 'Architecural Science'
)
courseName = models.CharField(max_length=250)
semester = models.CharField(
max_length = 20,
choices = SEMESTER_CHOICES,
default = 'SPR 21'
)
preRequisites = models.TextField()
def __str__ (self):
return self.courseName
and here is my views.py
from django.shortcuts import render
from .models import AddCourse
from django.contrib.auth.decorators import login_required
# Create your views here.
#login_required
def currentpathway(request):
return render(request, "SEAS_Course_Planner/home.html")
#login_required
def newpathway(request):
return render(request, "SEAS_Course_Planner/newpathway.html")
Nothing is printing out and I believe the object list is empty, but I've added courses via the admin page, any suggestions. Im new to Django as you can tell hahaha.

I think you need to go through the docs from beginning.
Here in your view first you need to return the queryset from your Course model and need to pass the queryset as a context in your template.
def currentpathway(request):
courses_list = AddCourse.objects.all()
context = {'courses_list':courses_list}
return render(request, "SEAS_Course_Planner/home.html", context)
Now in the template:
{% for course in courses_list %}
<li>{{ course.courseName}} </li>
{% endfor %}

Related

Django html display from model

I need on my html page to display data from Profesor and Ucenik model: ime, prezime, jmbg.
{{profesor.ime}}
{{profesor.prezime}}
{{ucenik.ime}}
{{ucenik.prezime}}
{{ucenik.jmbg}}
my profile page id dynamic, need to display profesor data or if ucenik to display ucenik data
what i need to add on my views.py
models.py
class Profesor(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
ime = models.CharField(max_length=200, null=True)
prezime = models.CharField(max_length=200, null=True)
class Ucenik(models.Model):
user = models.OneToOneField(User, null=True, blank=True, on_delete=models.CASCADE)
ime = models.CharField(max_length=200, null=True)
prezime = models.CharField(max_length=200, null=True)
jmbg = models.IntegerField(null=True)
urls.py
path('profesor/', views.profesor, name='profesor'),
path('ucenik/', views.ucenik, name='ucenik'),
path('posetioc/', views.posetioc, name='posetioc'),
path('profil/<str:pk>/', views.profil, name='profil'), ]
views.py
def profesor(request):
return render(request, 'pocetna_profesor.html')
def ucenik(request):
return render(request, 'pocetna_ucenik.html')
def profil(request, pk):
return render(request, 'profil.html')
HTML:
{% extends 'base.html' %}
<title>profesor</title>
{% block content %}
<body>
{% include 'navbar.html' %}
<h1>Ime:</h1>
{{profesor.ime}}
</body>
{% endblock %}
You need to add a Professor and Ucenik instance to your view context.
context = {
'professor': Professor.objects.get(),
'ucenik': Ucenik.objects.get()
}
return render(request, context, 'url.html')
You can make your profile view dynamic by introducing an extra parameter which defines your role (i.e, Professor/Ucenik)
/profil/profesor/2/ for profesor
/profil/ucenik/1 for ucenik
from django.urls import path
urlpatterns=[
path('profil/<str:role>/<int:pk>/', views.profil, name='profil'),
]
# views.py
from .models import Profesor,Ucenik # import your model
def profil(request,role,pk):
context = {}
context['role'] = type
if type=="profesor":
context['person'] = Profesor.objects.get(id=pk)
else:
context['person'] = Ucenik.objects.get(id=pk)
return render(request, 'profil.html',context)
<!-- profil.html -->
{% extends 'base.html' %}
<title>{{role}}</title>
{% block content %}
<body>
{% include 'navbar.html' %}
<h1>Ime:</h1>
{{person.ime}}
</body>
{% endblock %}
Different Approach:
Assuming your User Model is having an id or any unique field.
You could use that id to be your profil id (i.e, url's <int:pk>).
so instead of profil/profesor/3, you can use profil/3 which must be definitely one of two categories(assuming profesor and ucenik are mutually exclusive).
So in order to do that import User model into views along with other models.
views.py
from django.shortcuts import render
from ..models import User # give correct path to user model
from .models import Profesor,Ucenik
def profil(request,pk):
context={}
person = User.objects.get(id=pk)
try :
person.profesor
# print(dir(person))
except Profesor.DoesNotExist:
context['person'] = Ucenik.objects.get(id=person.ucenik.id)
else:
context['person'] = Profesor.objects.get(id=person.profesor.id)
return render(request,"profil.html",context)
urls.py
from django.urls import path
from .views import profil
urlpatterns = [
path('profil/<int:pk>/',profil) # I have used int
]
I used person,neutral variable name instead of profesor or ucenik.
You can name it anything even profil
profil.html
{{person.id}}
{{person.ime}}
{{person.prezime}}
{% if role == "ucenik" %}
{{person.jmbg}}
{% else %}
<!-- profesor does not have jmbg -->
{% endif %}

Tango with Django Chapter 6 - URL won't work

I have been going through "Tango with Django" and have been unable to solve this problem myself or by looking online. Would anyone know how to approach it?
The relevant page should be opened when I click on the link, but none are going through, which makes me assume something in my view.py file is wrong or even in my url.py or model.py file (index.html seems to be working correctly).
Views.py
# Create your views here.
from django.http import HttpResponse
from django.shortcuts import render
from Spaces.models import Category, Page
def index(request):
# Query the databse for a list of ALL categories currently stored.
# Order the categories by no likes in descending order .
# Retrieve the top 5 only - or all if less than 5.
# Place the list in context_dict dictionary
# that will be passed to the template engine.
category_list = Category.objects.order_by('-likes')[:5]
context_dict = {'categories': category_list}
# Render the response and send it back!
return render(request, 'Spaces/index.html', context=context_dict)
def about(request):
context_dict = {'boldmessage':"Crunchy, creamy, cookie, candy, cupcake!"}
return render(request, 'Spaces/about.html', context=context_dict)
def show_category(request, category_name_slug):
# Create a context dictionary which we can pass
# to the template rendering engine.
context_dict = {}
try:
# Can we find a category name slug with the given name?
# If we can't, the .get() method raises a DoesNotExist exception.
# So the .get() method returns one model instance or raises an exception.
category = Category.objects.get(slug=category_name_slug)
# Retrieve all of the associated pages.
# Note that filter() will return a list of page objects or an empty list
pages = Page.objects.filter(category=category)
# Adds our results list to the template context under name pages.
context_dict['pages'] = pages
# We also add the category object from
# the database to the context dictionary.
# We'll use this in the template to verify that the category exists.
context_dict['category'] = category
except Category.DoesNotExist:
# We get here if we didn't find the specified category.
# Don't do anything -
# the template will display the "no category" message for us.
context_dict['category'] = None
context_dict['pages'] = None
# Go render the response and return it to the client.
return render(request, 'Spaces/category.html', context_dict)
Urls.py
from django.conf.urls import url
from Spaces import views
urlpatterns = [
url(r'^$', views.index, name='index'),
url(r'^about/$', views.about, name='about'),
url(r'^category/(?P<category_name_slug>[\w\-]+)/$',
views.show_category, name='show_category'),
]
models.py
from django.db import models
from django.template.defaultfilters import slugify
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
views = models.IntegerField(default=0)
likes = models.IntegerField(default=0)
slug = models.SlugField(unique=True, blank=True, null=True)
def save(self, *args, **kwargs):
self.slug = slugify(self.name)
super(Category, self).save(*args, **kwargs)
class Meta:
verbose_name_plural = 'categories'
def __str__(self):
return self.name
class Page(models.Model):
category = models.ForeignKey(Category, on_delete=models.PROTECT)
title = models.CharField(max_length=128)
url = models.URLField()
views = models.IntegerField(default=0)
def __str__(self): # For Python 2, use __unicode__ too
return self.title
index.html
<!DOCTYPE html>
{% load staticfiles %}
<html>
<head>
<title>Spaces</title>
</head>
<body>
<h1>Spaces says...</h1>
<div>hey there partner!</div>
<div>
{% if categories %}
<ul>
{% for category in categories %}
<li>
{{ category.name }}
</li>
{% endfor %}
</ul>
{% else %}
<strong>There are no categories present.</strong>
{% endif %}
</div>
<div>
About Space<br />
<img src="{% static 'images/Spaces.jpg' %}" alt="Picture of Rango" />
</div>
</body>
</html>
populate_spaces.py (test script)
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE',
'Space.settings')
import django
django.setup()
from Spaces.models import Category, Page
def populate():
#First, we will create lists of dictionaries containing the pages
# we want to add into each category.
# Then we will create a dictionary of dictionaries for our categories.
# This might seem a little bit confusing, but it allows us to iterate
# through each data structure, and add the data to our models.
python_pages = [
{"title": "Prahran",
"url":"http://docs.python.org/2/tutorial/", "views":20},
{"title": "South Yarra",
"url":"http://docs.python.org/2/tutorial/", "views":25},
{"title": "etcetera",
"url":"http://docs.python.org/2/tutorial/", "views":35}
]
django_pages = [
{"title" : "Official Django Tutorial",
"url" :"https://docs.djangoproject.com/en/1.9/intro/tutorial01/", "views":36},
{"title":"Django Rocks",
"url":"http://www.djangorocks.com/", "views":23},
{"title":"How to Tango with Django",
"url":"http://www.tangowithdjango.com/", "views":45}
]
other_pages = [
{"title":"Bottle",
"url":"http://bottlepy.org/docs/dev/", "views":3},
{"title":"Flask",
"url":"http://flask.pocoo.org",
"views":34}]
cats = {"Python": {"pages": python_pages, "views": 128, "likes":64},
"Django": {"pages": django_pages, "views": 64, "likes":32},
"Other Frameworks": {"pages": other_pages, "views": 32, "likes":16} }
# If you want to add more categories or pages,
# Add them to the dictionaries above.
# The code below goes through the cats dictionary, then adds each category
# and then adds all the associated pages for that category.
for cat, cat_data in cats.items():
c = add_cat(cat,cat_data)
for p in cat_data["pages"]:
add_page(c, p["title"], p["url"], p["views"])
#Print out the categories we have added.
for c in Category.objects.all():
for p in Page.objects.filter(category=c):
print("-{0})-{1}".format(str(c), str(p)))
def add_page(cat, title, url, views=0):
p = Page.objects.get_or_create(category=cat, title=title)[0]
p.url=url
p.views=views
p.save()
return p
def add_cat(name, cat_data):
c = Category.objects.get_or_create(name=name)[0]
c.likes = cat_data["likes"]
c.views = cat_data["views"]
c.save()
return c
# Start execution here!
if __name__ == '__main__':
print("Starting Spaces population script...")
populate()
I fixed the issue.
Essentially I had indented a return function in my view.py file incorrectly!

type object 'Album' has no attribute 'object'

I'm new to Django and web coding.
I'm following Bucky tuts: Django Tutorial for Beginners - 29 - Generic Views
& I'm trying to get my music ( index ) page , but it gives me that error in the browser :
AttributeError at /music/ type object 'Album' has no attribute
'object'
& here's my views.py :
from django.http import HttpResponse, Http404
from django.shortcuts import render , get_object_or_404
from .models import Album,song
from django.views import generic
"""
def index(request):
all_albums = Album.objects.all()
context = {'all_albums': all_albums}
return render(request, 'music/index.html', context)
"""
class IndexView (generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
return Album.object.all()
'''
class DetailView (generic.DetailView):
model = Album
template_name = "music/details.html"
'''
def details(request, album_id):
try:
album = Album.objects.get(pk=album_id)
except Album.DoesNotExist:
raise Http404("Album Does Not Exists !")
return render(request, 'music/details.html', {'album': album})
def favourite (request , album_id):
album = get_object_or_404 (Album , pk=album_id)
try:
selected_song = album.song_set.get(pk=request.POST['song'])
except(KeyError, song.DoesNotExist):
return render(request, 'music/details.html', {
'album':album,
'error_message': "you entered wrong"
})
else:
selected_song.is_favorite = False
selected_song.save()
return render(request,'music/details.html' , {'album':album})
models.py
from django.db import models
# Create your models here.
class Album (models.Model):
artist = models.CharField(max_length = 100)
album_title = models.CharField(max_length = 100)
genre = models.CharField(max_length = 50)
album_logo = models.CharField(max_length = 1000)
def __str__(self):
return self.album_title + " - " + self.artist
class song (models.Model):
album = models.ForeignKey(Album , on_delete=models.CASCADE)
file_type = models.CharField(max_length = 10)
song_title = models.CharField(max_length = 100)
is_favourite = models.BooleanField(default=False)
def __str__(self):
return self.song_title
index.html
{% extends 'music/base.html' %}
{% block title %}Main : MuSiC {% endblock %}
{% block body %}
<ul>
{% for album in all_albums %}
<li>{{ album.album_title }}</li>
{% endfor %}
</ul>
{% endblock %}
#/music/{{ album.id }}
project structure
{ (website) project dir }
|-music
..|-migrations
..|-static
..|-templates
....|-music
......|-base.html
......|-details.html
......|-index.html
|-__init__.py
|-admin.py
|-apps.py
|-models.py
|-tests.py
|-urls.py
|-views.py
|-website
..|-__init__.py
..|-settings.py
..|-urls.py
..|-wsgi.py
|-db.sqlite3
|-manage.py
and I don't know where is the problem :(
btw, lot's of coding terms I still didn't learned , that's why I may ask alot ever I searched for a solution but didn't understand the answer from other question's answers .
Album.object does not exist; you should've written Album.objects.
class IndexView (generic.ListView):
template_name = 'music/index.html'
context_object_name = 'all_albums'
def get_queryset(self):
# return Album.object.all() <-- Remove this
return Album.objects.all()
As a side note, reserved words cannot be python attributes. This is by design, because disallowing these words makes parsing substantially easier.
Why can't attribute names be Python keywords?

Trouble with order.by('?') .first() to get random content in Django

Update #4:
The for loop in slider.html is currently not pulling content after the last update. Slider.html was randomized; however, I'm getting four of the same story and the urls are not going to their appropriate detailed view page anymore.
List.html has been fixed and is now random.
slider.html - This section is still wonky, (updated - 4:19 p.m.)
{% for random_article in random_articles %}
<div class="slider">
<div class="group visible">
<div class="sliderItem">
<img src="{{random_article.relatedImage}}" alt="" class="sliderPicture">
<p class="related">{{random_article.title}}</p>
</div><!-- /.sliderItem -->
</div><!-- /.group -->
</div><!-- /.slider -->
{% endfor %}
Here is the URL error when I click to detailed view:
NoReverseMatch at /last-us
Reverse for 'detailed' with arguments '()' and keyword arguments '{u'slug': ''}' not found. 1 pattern(s) tried: ['(?P<slug>\\S+)']
New culprits (for why slider.html isn't working)
urls.py
from django.conf.urls import patterns, url
from . import views
urlpatterns = patterns(
'',
url(r'^$', views.BlogIndex.as_view(), name="list"),
url(r'^(?P<slug>\S+)', views.BlogDetail.as_view(), name="detailed"),
)
views.py (updated - 4:19 p.m.)
Added context['random_slider'] = FullArticle.objects.order_by('?')[:4] but I don't think this is the right approach. So that I can get four different articles vs. four of the same article randomized.
from django.views import generic
from . import models
from .models import FullArticle
# Create your views here.
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
def get_context_data(self, **kwargs):
context = super(BlogIndex, self).get_context_data(**kwargs)
context['random_article'] = FullArticle.objects.order_by('?').first()
return context
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
def get_context_data(self, **kwargs):
context = super(BlogDetail, self).get_context_data(**kwargs)
context['object_list'] = models.FullArticle.objects.published()
return context
def get_context_data(self, **kwargs):
context = super(BlogDetail, self).get_context_data(**kwargs)
context['random_articles'] = FullArticle.objects.exclude(
pk=self.get_object().pk
).order_by('?')[:4]
return context
Original Problem
I'm using FullArticle.objects.order_by('?').first() to get a random article from my database, but it's currently giving the same article when I refresh the page. There is probably something missing from my models, view or how I'm calling it (using slice) in list.html or slider.html that is causing the problem.
The two parts I'm looking to make random on page load:
list.html (changed so that it's {{random_article.}} ) - This section of the problem is fixed.
<div class="mainContent clearfix">
<div class="wrapper">
<h1>Top 10 Video Games</h1>
{% for article in object_list|slice:":1" %}
<p class="date">{{article.pubDate|date:"l, F j, Y" }}</p> | <p class="author">{{article.author}}</p>
<img src="{{article.heroImage}}" alt="" class="mediumImage">
<p class="caption">{{article.body|truncatewords:"80"}}</p>
{% endfor %}
models.py
from django.db import models
from django.core.urlresolvers import reverse
# Create your models here.
class FullArticleQuerySet(models.QuerySet):
def published(self):
return self.filter(publish=True)
class FullArticle(models.Model):
title = models.CharField(max_length=150)
author = models.CharField(max_length=150)
slug = models.SlugField(max_length=200, unique=True)
pubDate = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
category = models.CharField(max_length=150)
heroImage = models.CharField(max_length=250, blank=True)
relatedImage = models.CharField(max_length=250, blank=True)
body = models.TextField()
publish = models.BooleanField(default=True)
gameRank = models.CharField(max_length=150, blank=True, null=True)
objects = FullArticleQuerySet.as_manager()
def __str__(self):
return self.title
def get_absolute_url(self):
return reverse("FullArticle_detailed", kwargs={"slug": self.slug})
class Meta:
verbose_name = "Blog entry"
verbose_name_plural = "Blog Entries"
ordering = ["-pubDate"]
The problem is that you are setting the value of a class attribute at "compile time" and not each time the view is called. Instead, you could do:
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
def random_article(self):
return = FullArticle.objects.order_by('?').first()
Or:
class BlogIndex(generic.ListView):
queryset = models.FullArticle.objects.published()
template_name = "list.html"
def get_context_data(self, **kwargs):
context = super(BlogIndex, self).get_context_data(**kwargs)
context['random_article'] = FullArticle.objects.order_by('?').first()
return context
[update]
In list html, I only need one random article. In slider.html, I need four random articles, would I just tack on FullArticle.objects.order_by('?')[:4] somewhere in that def get_context_data snippet?
Yes. Make it plural in the view (don't forget to exclude the main article from the side list):
class BlogDetail(generic.DetailView):
model = models.FullArticle
template_name = "detailed.html"
def get_context_data(self, **kwargs):
context = super(BlogDetail, self).get_context_data(**kwargs)
context['random_articles'] = FullArticle.objects.exclude(
pk=self.get_object().pk
).order_by('?')[:4]
return context
At the template, do:
{% for random_article in random_articles %}
<div class="sliderItem">
<img src="{{random_article.relatedImage}}" alt="" class="sliderPicture">
<p class="related">{{random_article.title}}</p>
</div><!-- /.sliderItem -->
{% endfor %}
The generic listview just passes an object_list as context based on the queryset. In your case it means you have to either change the value of queryset in your view or override the get_context_data method and add your random item to it.
https://docs.djangoproject.com/en/dev/ref/class-based-views/mixins-multiple-object/#django.views.generic.list.MultipleObjectMixin.get_context_data

How do I avoid "record already exists" form validation error using ModelForms in Django 1.6?

Following the ModelForm docs and using this model:
class ShippingLabel(models.Model):
"""Record what shipping lables were printed list"""
class Meta:
db_table = 'shipping_labels'
ordering = ('client',)
verbose_name = _('shipping label')
verbose_name_plural = _('shipping labels')
LAYOUT_LASER_2x2 = "1"
LAYOUT_TICKET = "2"
LAYOUT_LASER_1x1 = "3"
LAYOUT_CHOICES = (
( LAYOUT_LASER_1x1, _("Laser (1x1 sheet)") ),
( LAYOUT_LASER_2x2, _("Laser (2x2 sheet)") ),
( LAYOUT_TICKET, _("Ticket (3-inch wide)") ),
)
client = models.ForeignKey(Company, blank=False, null=False, unique=True, help_text=_("Which Client to ship to?"), verbose_name=_("client") )
store = models.ForeignKey(Store, blank=False, null=False, help_text=_("What store info should be used? (address, logo, phone, etc)"), verbose_name=_("store") )
packages = models.CharField(_("Packages"), max_length=30, blank=False, null=False, help_text=_("Total number of packages. One label printed per package.") )
preprinted_form = models.BooleanField(_("Pre-Printed Form"), default=False, help_text=_("Are you using pre-printed shipping label stickers?"), )
layout = models.CharField(_("Record Type"), max_length=10, blank=False, null=False, choices=LAYOUT_CHOICES, default=LAYOUT_LASER_1x1, help_text=_("Print on large labels (4 per Letter page), Laser large labels (1 per page), or ticket printer?") )
added_by = models.CharField(_("Added By"), max_length=30, blank=True, null=True, help_text=_("The User that created this order.") )
date_added = models.DateTimeField(_('Date added'), auto_now_add=True)
date_modified = models.DateTimeField(_('Date modified'), auto_now=True)
def get_absolute_url(self):
return reverse('shipping:printship', args=[str(self.id)])
def __unicode__(self):
return unicode(self.client)
I made this form template following their example (manual_label.html):
{% extends "admin/base_site.html" %}
{% load i18n %}
{% load staticfiles %}
{% block extrahead %}
{{ block.super}}
<script src="{{ STATIC_URL }}js/jquery-1.11.1.js"></script>
{% endblock %}
{% block content %}
<form id="manual_label" method="post" action="">
{% csrf_token %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
<table>
{{ form.as_table }}
</table>
<input type="submit" value="generar etiquetas autoadhesivas"/>
</form>
<p>
</p>
{% endblock %}
My app urls.py:
from django.conf.urls import patterns, url
from shipping.views import printship, pcustomer, manual_label
urlpatterns = patterns('',
url(r'pcust/', pcustomer, name='pcustomer'),
url(r'mlabel/([0-9]+)/$', manual_label, name='manual_label'),
url(r'printlabel/([0-9]+)/$', printship, name='printship'),
)
My view (with lots of diagnostic logging):
#login_required()
def manual_label(request, id):
logger.debug("SHIPPING.VIEWS.manual_label")
if request.method == 'POST':
logger.debug("SHIPPING.VIEWS.manual_label: POST!")
client = get_object_or_404(Company, pk=id)
labelset = ShippingLabel.objects.filter(client=client)
if len(labelset)>0:
# Pre-existing label, update it:
logger.debug("SHIPPING.VIEWS.manual_label.POST: Update a label!")
label = labelset[0]
form = ShipLabelForm(request.POST, instance=label)
else:
# New label:
logger.debug("SHIPPING.VIEWS.manual_label.POST: Save New label!")
form = ShipLabelForm(request.POST)
if form.is_valid():
logger.debug("SHIPPING.VIEWS.manual_label.POST: form is valid")
label = form.save(commit=True)
logger.debug("SHIPPING.VIEWS.manual_label.POST: label pk: " + str(label.id) )
logger.debug("SHIPPING.VIEWS.manual_label.POST: label client name: " + str(label.client.name) )
logger.debug("SHIPPING.VIEWS.manual_label: post return")
return HttpResponseRedirect(reverse('shipping:printship', args=[str(label.id)]))
else:
logger.debug("SHIPPING.VIEWS.manual_label: GET!")
client = get_object_or_404(Company, pk=id)
labelset = ShippingLabel.objects.filter(client=client)
if len(labelset)>0:
# Pre-existing label, load it:
logger.debug("SHIPPING.VIEWS.manual_label: Pre-Existing label, load it...")
label = labelset[0]
form = ShipLabelForm(instance=label)
else:
# New label:
label = ShippingLabel(client=client,
store=request.user.employee.store,
added_by=request.user.get_username())
form = ShipLabelForm(instance=label)
logger.debug("SHIPPING.VIEWS.manual_label: get return")
return render(request, 'shipping/manual_label.html', {
'title': u"Creación de etiquetas Manual Envios",
'form': form,
})
My forms.py definition:
class ShipLabelForm(ModelForm):
class Meta:
model = ShippingLabel
localized_fields = '__all__'
fields = '__all__'
widgets = {
'added_by': HiddenInput,
'id': HiddenInput,
}
I added 'id': HiddenInput, to try and "force" record ID number to get sent out to the form, in the theory that my error occurs because without the ID number, Django will validate in "ADD" mode which will certainly trigger the "unique" flag I have on clients.
The manual_label view is called by a customer selection form, passing in the client id. The goal is to generate an ADD form if there is currently no shipping label for this client defined - which works.
And if a shipping label already exists, I pre-load the form with its data. The idea being I thought the form system would automatically do an UPDATE on the existing record.
In either case, the saved shipping label record is used to generate the shipping labels desired.
This works in the admin view (using view on site). But I wanted to give the users a simpler system. This works fine for ADDing new labels. But when I try to EDIT an existing label, I get a form validation error "client already exists".
It seemed like such an easy thing to do....
So, what am I missing tor doing wrong?
You should be using the instance argument when initializing the form, both in the POST and GET blocks.

Categories