Django page & category names showing as objects - python-3.4

This code is showing page and category names as objects and not by their respective title. Its supposed to show the names and its showing page objects and category objects instead for all the titles
import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'mysite.settings')
import django
django.setup()
from rango.models import Category, Page
def populate():
python_cat = add_cat('Python')
add_page(cat=python_cat,
title="Official Python Tutorial",
url="http://docs.python.org/2/tutorial/")
add_page(cat=python_cat,
title="How to Think like a Computer Scientist",
url="http://www.greenteapress.com/thinkpython/")
add_page(cat=python_cat,
title="Learn Python in 10 Minutes",
url="http://www.korokithakis.net/tutorials/python/")
django_cat = add_cat("Django")
add_page(cat=django_cat,
title="Official Django Tutorial",
url="https://docs.djangoproject.com/en/1.5/intro/tutorial01/")
add_page(cat=django_cat,
title="Django Rocks",
url="http://www.djangorocks.com/")
add_page(cat=django_cat,
title="How to Tango with Django",
url="http://www.tangowithdjango.com/")
frame_cat = add_cat("Other Frameworks")
add_page(cat=frame_cat,
title="Bottle",
url="http://bottlepy.org/docs/dev/")
add_page(cat=frame_cat,
title="Flask",
url="http://flask.pocoo.org")
# Print out what we have added to the user.
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, url=url, views=views)[0]
return p
def add_cat(name):
c = Category.objects.get_or_create(name=name)[0]
return c
# Start execution here!
if __name__ == '__main__':
print ("Starting Rango population script...")
populate()
What is wrong with the code or is the fault is with another file ? Using python 3.4 and django 1.7. Have I missed a file ? is there an other file I should share?

I had the same problem while studying through django with tango. I missed the method in the rango/modules.py in the class Page.
def str(self): # For Python 2, use unicode too
return self.title

__unicode__(self) seems to be creating the problem for Python-3 . Replace that with __str__(self) and it should work.
from django.db import models
class Category(models.Model):
name = models.CharField(max_length=128, unique=True)
def __str__(self):
return self.name
class Page(models.Model):
category = models.ForeignKey(Category)
title = models.CharField(max_length = 128)
url = models.URLField()
views = models.IntegerField(default=0)
def __str__(self):
return self.title

Related

" __conform__() is not a valid Streamlit command."

While I was running my code in pycharm, it is showing:
__conform__() is not a valid Streamlit command."
I am trying to store input and result in my streamlit app in sqlite3 database and and display it in tabular format in same streamlit app.
Main code page:home_task.py:
import streamlit as st
from homework_db import create_table, add_data
def main():
st.title("Streamlit Exercise")
menu = ['Insert', 'Read']
choice = st.sidebar.selectbox("Menu", menu)
create_table()
if choice == 'Insert':
st.subheader('Lets check Sentiment')
line = st.text_area("Enter the sentence")
result = st.text("Positive")
if st.button("Add Task"):
add_data(line, result)
st.success("Successfully added data in database")
elif choice == 'Read':
st.subheader('Datatable')
if __name__ == "__main__":
main()
The other file: homework_db.py:
import sqlite3
conn = sqlite3.connect("homework2_db", check_same_thread=False)
c = conn.cursor()
## database-table-field-datatype##
def create_table():
c.execute('CREATE TABLE IF NOT EXISTS database(sentence TEXT, sentiment TEXT)')
def add_data(line, result):
c.execute('INSERT INTO database(sentence,sentiment) VALUES(?,?)', (line, result))
conn.commit()
Everything seems fine, I have followed many youtube videos for sql query, it seems right but I am not sure why streamlit is not accepting the code.
I also checked python docs, (https://docs.python.org/3.6/library/sqlite3.html#letting-your-object-adapt-itself) but could not figure out how this is related to my problem.
It's because result is not a string but a Streamlit object:
>>> import streamlit
>>> result = st.text("Positive")
>>> type(result)
<class 'streamlit.delta_generator.DeltaGenerator'>
What you need is to do is remove the st.text():
if choice == 'Insert':
st.subheader('Lets check Sentiment')
line = st.text_area("Enter the sentence")
result = "Positive" # no st.text()
if st.button("Add Task"):
add_data(line, result)
st.success("Successfully added data in database")

Python - BaseHTTPServer , issue with POST and GET

I am making a very simple application with 2 webpages at the moment under URLs: localhost:8080/restaurants/ and localhost:8080/restaurants/new.
I have a sqlite database which i manipulate with SQLAlchemy in my python code.
On my first page localhost:8080/restaurants/, this just contains the lists of restaurants available in my database.
My second page localhost:8080/restaurants/new, is where i have a form in order to a new restaurant such that it displays on localhost:8080/restaurants.
However Whenever i enter a new restaurant name on form at localhost:8080/restaurants/new, it fails to redirect me back to localhost:8080/restaurants/ in order to show me the new restaurant, instead it just remains on the same url link localhost:8080/restaurants/new with the message "No data received" .
Below is my code:
import cgi
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
#import libraries and modules
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database_setup import Base, Restaurant, MenuItem
#create and connect to database
engine = create_engine('sqlite:///restaurantmenu.db')
Base.metadata.bind=engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
class webServerHandler(BaseHTTPRequestHandler):
""" class defined in the main method"""
def do_GET(self):
try:
#look for url then ends with '/hello'
if self.path.endswith("/restaurants"):
self.send_response(200)
#indicate reply in form of html to the client
self.send_header('Content-type', 'text/html')
#indicates end of https headers in the response
self.end_headers()
#obtain all restaurant names from databse
restaurants = session.query(Restaurant).all()
output = ""
output += "<html><body><a href='/restaurants/new'>Add A New Restaurant</a>"
output += "</br></br>"
for restaurant in restaurants:
output += restaurant.name
output += """<div>
<a href='#'>Edit</a>
<a href='#'>Delete</a>
</div>"""
output += "</br></br>"
output += "</body></html>"
self.wfile.write(output)
print output
return
if self.path.endswith("/restaurants/new"):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
output = ""
output += "<html><body>"
output += "<h1>Add New Restaurant</h1>"
output += "<form method='POST' enctype='multipart/form-data action='/restaurants/new'>"
output += "<input name='newRestaurant' type='text' placeholder='New Restaurant Name'>"
output += "<input name='Create' type='submit' label='Create'>"
output += "</form></body></html>"
self.wfile.write(output)
return
except IOError:
self.send_error(404, "File %s not found" % self.path)
def do_POST(self):
try:
if self.path.endswith("/restaurants/new"):
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
#check of content-type is form
if ctype == 'mulitpart/form-data':
#collect all fields from form, fields is a dictionary
fields = cgi.parse_multipart(self.rfile, pdict)
#extract the name of the restaurant from the form
messagecontent = fields.get('newRestaurant')
#create the new object
newRestaurantName = Restaurant(name = messagecontent[0])
session.add(newRestaurantName)
session.commit()
self.send_response(301)
self.send_header('Content-type', 'text/html')
self.send_header('Location','/restaurants')
self.end_headers()
except:
pass
def main():
"""An instance of HTTPServer is created in the main method
HTTPServer is built off of a TCP server indicating the
transmission protocol
"""
try:
port = 8080
#server address is tuple & contains host and port number
#host is an empty string in this case
server = HTTPServer(('', port), webServerHandler)
print "Web server running on port %s" % port
#keep server continually listening until interrupt occurs
server.serve_forever()
except KeyboardInterrupt:
print "^C entered, stopping web server...."
#shut down server
server.socket.close()
#run main method
if __name__ == '__main__':
main()
for reference here is my database_setup file where i create the database:
import sys
#importing classes from sqlalchemy module
from sqlalchemy import Column, ForeignKey, Integer, String
#delcaritive_base , used in the configuration
# and class code, used when writing mapper
from sqlalchemy.ext.declarative import declarative_base
#relationship in order to create foreign key relationship
#used when writing the mapper
from sqlalchemy.orm import relationship
#create_engine to used in the configuration code at the
#end of the file
from sqlalchemy import create_engine
#this object will help set up when writing the class code
Base = declarative_base()
class Restaurant(Base):
"""
class Restaurant corresponds to restaurant table
in the database to be created.
table representation for restaurant which
is in the database
"""
__tablename__ = 'restaurant'
#column definitions for the restaurant table
id = Column(Integer, primary_key=True)
name = Column(String(250), nullable=False)
class MenuItem(Base):
"""
class MenuItem corresponds to restaurant table
table representation for menu_item which
is in the database
"""
__tablename__ = 'menu_item'
#column definitions for the restaurant table
name = Column(String(80), nullable=False)
id = Column(Integer, primary_key=True)
course = Column(String(250))
description = Column(String(250))
price = Column(String(8))
restaurant_id = Column(Integer, ForeignKey('restaurant.id'))
restaurant = relationship(Restaurant)
#create an instance of create_engine class
#and point to the database to be used
engine = create_engine(
'sqlite:///restaurantmenu.db')
#that will soon be added into the database. makes
#the engine
Base.metadata.create_all(engine)
I can't figure out why i cannot add new restuarants
I know this was a long time ago, but I figured out your problem.
First, the enctype='multipart/form-data' in your do_GET function under the if self.path.endswith("/restaurants/new"): portion is missing a final single quote. Second, you misspelt 'multipart' in if ctype == 'multipart/form-data':. Hope that can help you or others.
As shteeven said, the problem was with the encryption type in the form.
As the quote was missed, the 'Content-type' changed to 'application/x-www-form-urlencoded' so in that case you should parse it different as it's a string.
In order to manage both enctype you can modify your do_POST as the following
def do_POST(self):
try:
if self.path.endswith("/restaurants/new"):
ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
print ctype
#check of content-type is form
if (ctype == 'multipart/form-data') or (ctype == 'application/x-www-form-urlencoded'):
#collect all fields from form, fields is a dictionary
if ctype == 'multipart/form-data':
fields = cgi.parse_multipart(self.rfile, pdict)
else:
content_length = self.headers.getheaders('Content-length')
length = int(content_length[0])
body = self.rfile.read(length)
fields = urlparse.parse_qs(body)
#extract the name of the restaurant from the form
messagecontent = fields.get('newRestaurant')
#create the new object
newRestaurantName = Restaurant(name = messagecontent[0])
session.add(newRestaurantName)
session.commit()
self.send_response(301)
self.send_header('Location','/restaurants')
self.end_headers()
return
Hope this extra information is useful for you!

Capturing Button Methods from a second Form using PyQT

I am super new to PyQT ... I am using QT Designer for my forms. I am confused about where to put my event handling for the second form in my project.
I have the following .py files :
main.py
Ui_make_render_folders.py (generated from the Qt designer ui file)
Ui_prefs.py (generated from the Qt designer ui file)
Mainwindow.py (this is where all the even handling for the main form
lives)
icons_rc.py (resource file)
make_render_folders.py (where all my custom functions live)
Here is a picture of the script running :
click to see script running << CLICK HERE
My question is ... where does the even handling for my prefs window go ???? I cant figure out where to put my [b]on_btn_released() for the buttons on y 2nd form.[/b] Also I am not sure I am instantiating that dialog properly. Currently I am adding this code to the top of my MainWindow.py.
Finally what does #pyqSignature("") do ? And do I need it ?
"""
This is where all teh MainWindow logic sits
"""
import os
import os.path
from PyQt4.QtGui import QMainWindow, QFileDialog, QTreeWidgetItem, QDialog
from PyQt4.QtCore import pyqtSignature, QString
from make_folders import make_render_folders
from Ui_make_render_folders import Ui_MainWindow
from Ui_prefs import Ui_prefs
class Prefs(QDialog, Ui_prefs):
def __init__(self, parent = None):
QDialog.__init__(self, parent)
self.setupUi(self)
#pyqtSignature("")
def on_btn_get_ref_dir_released(self):
print '2nd form'
class MainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent = None):
"""
Constructor
"""
QMainWindow.__init__(self, parent)
self.setupUi(self)
self.prefs = QDialog()
ui = Ui_prefs()
ui.setupUi(self.prefs)
#pyqtSignature("")
def on_btn_process_released(self):
print 'process'
no_of_shots = self.spn_no_of_shots.value()
#spot_path = self.le_proj_path.text()+'\\'+self.lst_spots.selectedItems()[0].text()
spot_path_string = 'self.le_proj_path.text())+os.sep,'
spot_path_string += str(self.lst_spots.selectedItems()[0].text())
os.path.join(spot_path_string)
save_position = self.lst_spots.selectedItems()[0]
if no_of_shots > 0:
if self.cmb_mode.currentText() == 'Create Shots':
print ('creating shots')
for x in range(1, no_of_shots+1):
make_render_folders.create_shot_folder(spot_path, x)
else:
print ('inserting shots')
if self.lst_shots.count() > 0:
t =self.lst_shots.selectedItems()[0].text()
cur_shot = t[2:]
cur_shot_val = int(cur_shot)
cur_index = self.lst_shots.currentRow()
print('sel_value :'+cur_shot)
print('sel_index :'+str(cur_index))
next_shot_index = int(cur_index)+1
print('nextshot_index ='+str(next_shot_index))
next_shot_text = self.lst_shots.item(next_shot_index).text()
next_shot_val = int(next_shot_text[2:])
print('nextshot value ='+str(next_shot_val))
insert_space = next_shot_val - cur_shot_val
print(str(insert_space))
if no_of_shots > (insert_space-1) :
print "not enough space - please reduce shots to insert"
else:
print('insert the shots')
for x in range(cur_shot_val,(cur_shot_val+no_of_shots) ):
print (str(x))
make_render_folders.insert_shot_folder(spot_path, x+1)
make_render_folders.populate_shot_list(self)
self.lst_shots.setCurrentRow(0)
#pyqtSignature("")
def on_btn_quit_released(self):
print 'quit'
self.close()
#pyqtSignature("")
def on_cmb_mode_currentIndexChanged(self, ret_text):
print ret_text
#pyqtSignature("")
def on_le_proj_path_editingFinished(self):
print "editingFinished le_proj_path"
def on_le_new_spot_name_textChanged(self):
if len(self.le_new_spot_name.text()) > 0 :
self.btn_add_spot.setEnabled(True)
else :
self.btn_add_spot.setEnabled(False)
#pyqtSignature("")
def on_btn_add_spot_released(self):
v_NewSpotFolder = self.le_new_spot_name.text()
v_rPath = self.le_proj_path.text()
x = make_render_folders.create_spot_folder(v_NewSpotFolder,v_rPath)
if x :
self.le_new_spot_name.clear()
make_render_folders.populate_spots_list(self)
#pyqtSignature("")
def on_actionLoad_Project_triggered(self):
print "actionLoad_Project"
self.lst_shots.clear()
self.lst_spots.clear()
proj_dir = str(QFileDialog.getExistingDirectory(self, 'Select Project'))
print proj_dir
if os.path.exists(proj_dir):
print 'the file is there'
elif os.access(os.path.dirname(proj_dir), os.W_OK):
print 'the file does not exists but write privileges are given'
else:
print 'can not write there'
p = os.path.join(proj_dir+os.sep,'renders')
self.le_proj_path.setText(p)
make_render_folders.populate_spots_list(self)
#pyqtSignature("")
def on_actionConfig_triggered(self):
print "config"
self.prefs.show()
#pyqtSignature("")
def on_actionQuit_triggered(self):
print "ActionQuit"
#pyqtSignature("")
def on_btn_get_folders_released(self):
make_render_folders.populate_spots_list(self)
def on_lst_spots_itemClicked (self):
print "got you"
self.lst_shots.clear()
make_render_folders.populate_shot_list(self)
Thanks !!!
Event handling for the Prefs window can go anywhere. Personally I always prefer to give each window its own file.
So the py files would look something like:
Mainwindow.py (Main form events etc)
Ui_make_render_folders.py (Qt Designer generated UI)
prefs.py (Prefs form events etc)
ui_prefs.py (Qt Designer generated UI)
your other files...
Initialisation: (MainWindow.py)
from PyQt4.QtGui import QMainWindow
from Ui_make_render_folders import Ui_MainWindow
#prefs here refers to the file: prefs.py. PrefWindow is the class within this file.
from prefs import PrefWindow
class MainWindow(QMainWindow):
def __init__(self, parent=None):
#Better way to initialise
super(MainWindow, self).__init__(parent)
self.main = Ui_MainWindow()
self.main.setupUi(self)
#initialise prefs to variable
self.prefs = PrefWindow(self)
# Rest of init...
Note: initialising of second form will be similar to above.
You should place all events for prefs form within its class.
From the function that calls Prefs:
#pyqtSlot()
def on_actionConfig_triggered(self):
print "config"
self.prefs.exec_() # Will block main window while its open.
# Use self.prefs.show() if you want user to be able to interact with main window
Finally: pyqtSignature
On http://pyqt.sourceforge.net/Docs/PyQt4/old_style_signals_slots.html it states that:
'The QtCore.pyqtSignature() serves the same purpose as the pyqtSlot() decorator but has a less Pythonic API.'
Better to use pyqtSlot()

GTK TreeView with ListStore don't display anything. Python and SQLite3 used

I use GTK and Python for developing an application.
I want to load TreeView elements (1 column) from SQLite3 database.
But something go wrong (without any error)!
Here is a whole code:
#!/usr/bin/python
import sys
import sqlite3 as sqlite
from gi.repository import Gtk
from gi.repository import Notify
def notify(notifer, text, notificationtype=""):
Notify.init("Application")
notification = Notify.Notification.new (notifer, text, notificationtype)
notification.show ()
def get_object(gtkname):
builder = Gtk.Builder()
builder.add_from_file("main.ui")
return builder.get_object(gtkname)
def base_connect(basefile):
return sqlite.connect(basefile)
class Handler:
def main_destroy(self, *args):
Gtk.main_quit(*args)
def hardwaretool_clicked(self, widget):
baselist = get_object("subjectlist")
baselist.clear()
base = base_connect("subjectbase")
with base:
cur = base.cursor()
cur.execute("SELECT * FROM sub")
while True:
row = cur.fetchone()
if row == None:
break
iter = baselist.append()
print "row ", row[0]
baselist.set(iter, 0, row[0])
cur.close()
def gamestool_clicked(self, widget):
print("gamestool clicked!!!!! =)")
def appstool_clicked(self, widget):
print("appstool clicked!!!!! =)")
def fixtool_clicked(self, widget):
notify("Charmix","Fix Applied", "dialog-ok")
def brokenfixtool_clicked(self, widget):
notify("Charmix","Broken Fix Report Sended", "dialog-error")
def sendfixtool_clicked(self, widget):
notify("Charmix","Fix Sended", "dialog-information")
class CharmixMain:
def __init__(self):
builder = Gtk.Builder()
builder.add_from_file("main.ui")
self.window = builder.get_object("main")
self.subject = builder.get_object("subjectlist")
self.problem = builder.get_object("problemlist")
self.toolbar = builder.get_object("toolbar")
self.hardwaretool = builder.get_object("hardwaretool")
self.gamestool = builder.get_object("gamestool")
self.appstool = builder.get_object("appstool")
self.fixtool = builder.get_object("fixtool")
self.brokenfixtool = builder.get_object("brokenfixtool")
self.sendfixtool = builder.get_object("sendfixtool")
builder.connect_signals(Handler())
context = self.toolbar.get_style_context()
context.add_class(Gtk.STYLE_CLASS_PRIMARY_TOOLBAR)
if __name__ == "__main__":
Charmix = CharmixMain()
Charmix.window.show()
Gtk.main()
I'm interested in this part (not working normally):
def hardwaretool_clicked(self, widget):
baselist = get_object("subjectlist")
baselist.clear()
base = base_connect("subjectbase")
with base:
cur = base.cursor()
cur.execute("SELECT * FROM sub")
while True:
row = cur.fetchone()
if row == None:
break
iter = baselist.append()
print "row ", row[0]
baselist.set(iter, 0, row[0])
cur.close()
TreeView(subjecttree) don't display anything, but print "row ", row[0] works fine and display all the strings.
Please, help me.
Maybe i need to repaint TreeView or thomething like that?
Do you know, how can I get it?
The problem is in your get_object method.
When you do:
builder = Gtk.Builder()
builder.add_from_file("main.ui")
you're actually creating a new window; even if you are using the same ui file, you are creating a completely different widget.
One way to get around the problem of accesing the widgets you need to process with your handler is to pass them as parameter of the constructor:
class Handler(object):
def __init__(self, widget1, widget2):
self.widget1 = widget1
self.widget2 = widget2
...
You can use those widgets on the handler's method afterwards.
Another way of accesing the widgets in a more 'decoupled' way is to add the object you want to use as the last parameter of the connect method when you're connecting signals; the drawback is that you would have to do this manually (since Glade doesn't provide this posibility)
self.widget.connect('some-signal', handler.handler_method, object_to_use)

Django-MPTT full path to child pages how to make?

I'm start using Django-MPTT app to get a tree-based approach on my Django-site pages.
For ex. I have pages with sub pages:
Trance:
Vocal Trance(sub page)
Hard Trance(sub page)
Breaks:
Atmo Breaks(sub page)
Progressive Breaks(sub page)
How can I get access to them from urls.py?
What pattern will help?
Do I need to store Full_path in model or it can be done via url pattern?
I assume you mean you want to do URLs like this:
/trance/
/trance/vocal-trance/
/trance/hard-trace/
/breaks/
/breaks/atmo-breaks/
/breaks/progressive-breaks/
If so, it's probably best to store the url fragment in your model. Something like:
from mptt.models import MPTTModel
from django.db import models
from django.template.defaultfilters import slugify
class Page(MPTTModel):
name = models.CharField(max_length=50)
slug = models.CharField(max_length=50,null=True)
url = models.CharField(max_length=255,null=True)
def save(self, *args, **kwargs)
if self.slug is None:
# create a slug that's unique to siblings
slug = slugify(self.name)
self.slug = slug
siblings = self.get_siblings()
i = 1
while siblings.filter(slug=self.slug).exists():
i += 1
self.slug = slug + '-%d' % i
# now create a URL based on parent's url + slug
if self.parent:
self.url = '%s/%s' % (self.parent.url, self.slug)
else:
self.url = self.slug
super(Page, self).save(*args, **kwargs)
Then add a URL pattern:
(r'^pages/(?P<page_url>[\w\d_/-]+)/$', 'pages.views.show_page'),
And in your view you can just fetch the right page:
def show_page(request, page_url=None):
page = get_object_or_404(Page, url=page_url)
...
Thank you for your attention to my problem.
See,How I finally do it.
models.py
class WebPage(MPTTModel):
slug=RuSlugField(max_length=20,unique=True)
title=models.CharField(max_length=50)
content=models.TextField()
parent=TreeForeignKey('self',null=True,blank=True,related_name='children')
class MPTTMeta:
order_insertion_by=['slug']
def get_absolute_url(self):#TODO:: replace with get_ancestors
url = "/%s/" % self.slug
page = self
while page.parent:
url = "/%s%s" % (page.parent.slug,url)
page = page.parent
return url
urls.py
urlpatterns = patterns('website.views',
url(r"^add/$", "add_page",name="add"),
url(r"^(?P<full_slug>.*)/add/$", "add_page",name="add"),
url(r"^(?P<full_slug>.*)/edit/$", "edit_page",name="edit"),
url(r'^$', ListView.as_view(model=WebPage,template_name='index.html',context_object_name="webpages_list",),name='index'),
url(r"^(?P<full_slug>.*)/$", "page", name="page"),
)
views.py
def page(request, full_slug):
# Make a list from full_slug.
# For ex. /trance/progressive_trance/fonarev -> ['trance','progressive_trance','fonarev']
slugs=full_slug.split('/')
page=None
# Get a page by it's slug
if len(slugs)>1:
page=get_object_or_404(WebPage,slug=slugs[-1])#slugs=['trance','vocal_trance'] -> 'vocal_trance'
elif len(slugs)==1:
page=get_object_or_404(WebPage,slug=slugs[0])#slugs=['trance'] -> 'trance'
# Check if page url matches requested full_slug
if page.get_absolute_url().strip('/') == full_slug:
return render_to_response('page.html', {'page': page},context_instance=RequestContext(request))
else:
raise Http404
def edit_page(request,full_slug):
slugs=full_slug.split('/')
page=None
if len(slugs)>1:
page=get_object_or_404(WebPage,slug=slugs[-1])
elif len(slugs)==1:
page=get_object_or_404(WebPage,slug=slugs[0])
if not page.get_absolute_url().strip('/') == full_slug:
raise Http404
# Send POST data for update an existing page.Update a page.
if request.method=='POST':
form=WebPageForm(request.POST, instance=page)
if form.is_valid():
form.save()
return HttpResponseRedirect(page.get_absolute_url())
# Render a form to edit data for existing page
else:
form=WebPageForm(instance=page)
return render_to_response('edit_page.html',{'form':form,},context_instance=RequestContext(request))
def add_page(request,full_slug=None):
parent_page=None
slug=None
if full_slug:
slug=full_slug.split('/')
# If there is a slug in REQUEST(ex.'trance')->we need to add a new_page to her parent_page.
# So get a parent page.
if slug:
if len(slug)>1:
parent_page=get_object_or_404(WebPage,slug=slug[-1])
elif len(slug)==1:
parent_page=get_object_or_404(WebPage,slug=slug[0])
# Create a new_page
if request.method=='POST':
form=WebPageForm(request.POST)
if form.is_valid():
new_page=form.save(commit=False)
if parent_page:
new_page.parent=parent_page
new_page.save()
return HttpResponseRedirect(new_page.get_absolute_url())
# Return an unbounded form
else:
form=WebPageForm()
return render_to_response('add_page.html',{'form':form,},context_instance=RequestContext(request))
The trick is in we have to check if the page really exists accessing to it via full_slug:
if not page.get_absolute_url().strip('/') == full_slug:
raise Http404
Otherwise, it could be wrong allowing to check only by slug.
There's also a django app that will do the work for you: django-mptt-urls
def get_absolute_url(self):
return '/'.join([x['slug'] for x in self.get_ancestors(include_self=True).values()])

Resources