Prevent field from being save into Django Model - django-models

I am creating a form that allow user to edit all the fields in the form. I would like to check with the community if there is a viable solution to display say the object ID in the form itself but when the user submit the updates, it will save the other fields and will not save the object ID?
Currently, I am prevented from saving due to the error: "ID already in database"
I have tried to add the attributes "readonly"; "disabled" but these are not working.
I am using {{form.as_p}} to display all the fields in my templates (HTML)
My apologies that I am not able to show the codes as it is on my corporate server.
Much help appreciated

Let assume that user want to update 'First name', then here below is technic to update authenticated user 'First name':
forms.py
from django import forms
from django.contrib.auth.models import User
class EditUserForm(forms.ModelForm):
class Meta:
model = User # You can provide model class here to update
fields = ['first_name'] # You can provide any field you want to update
views.py
from .forms import EditUserForm
from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required
#login_required
def edit_user(request): # give a url path with name='edit_user' in urls.py file
user = User.objects.filter(id=request.user.id).first() # Here you can write your model name which you want to update
form = EditUserForm(request.POST or None, instance=user)
if form.is_valid():
form.save() # that's it
return redirect('/') # redirect to wherever you want
return render(request,'update.html',{'form':form}) # provide template name here
update.html
<h1>Update First name:- </h1>
<form action="{% url 'edit_user' %}" method=POST>
{{form.as_p}}
<button type='submit'>Update</button>
</form>
Now, try it manually and you able to change the 'First name'. After that you get some confidence how you update any field of models.

Related

Django Dynamic model register in admin

I'm using django 1.11 and I tried to to create django dynamic models by referring this link https://code.djangoproject.com/wiki/DynamicModels , by executing each and every step it runs without any issue, but How can I see this created table in django admin panel?
action.py
from django.db import models
from django.contrib import admin
def create_model(name, fields=None, app_label='', module='', options=None, admin_opts=None):
"""
Create specified model
"""
class Meta:
# Using type('Meta', ...) gives a dictproxy error during model creation
pass
if app_label:
# app_label must be set using the Meta inner class
setattr(Meta, 'app_label', app_label)
# Update Meta with any options that were provided
if options is not None:
for key, value in options.iteritems():
setattr(Meta, key, value)
# Set up a dictionary to simulate declarations within a class
attrs = {'__module__': module, 'Meta': Meta}
# Add in any fields that were provided
if fields:
attrs.update(fields)
# Create the class, which automatically triggers ModelBase processing
model = type(name, (models.Model,), attrs)
# Create an Admin class if admin options were provided
if admin_opts is not None:
print admin_opts
class Admin(admin.ModelAdmin):
pass
for key, value in admin_opts:
setattr(Admin, key, value)
admin.site.register(model, Admin)
return model
In Console:
from action import create_model
from django.db import models
fields = {
'first_name': models.CharField(max_length=255),
'last_name': models.CharField(max_length=255),
'__str__': lambda self: '%s %s' (self.first_name, self.last_name),
}
options = {
'ordering': ['last_name', 'first_name'],
'verbose_name': 'valued customer',
}
admin_opts = {}
model = create_model('Person', fields,
options=options,
admin_opts=admin_opts,
app_label='form',
module='project.app.model',
)
I can see no. of fields by
len(model._meta.fields)
But I have no idea of, how to register the created model in admin, and what parameter will come inside admin_opts = {} , how can i do makemigrations and migrate,how can I access this model in views.py, from where i will import this model .Can you guys please help me for this , it will be very useful for me and Thanks in advance.
with connection.schema_editor() as editor:
editor.create_model(Model)
This is from github source code , try it instead of sql_model_create and I try to success in my project,and it's true..
I have worked hard for a long time because I don't find django-dynamic-model in "django 1.10".
I think you forgot to execute this function.
def install(model):
from django.core.management import sql, color
from django.db import connection
# Standard syncdb expects models to be in reliable locations,
# so dynamic models need to bypass django.core.management.syncdb.
# On the plus side, this allows individual models to be installed
# without installing the entire project structure.
# On the other hand, this means that things like relationships and
# indexes will have to be handled manually.
# This installs only the basic table definition.
# disable terminal colors in the sql statements
style = color.no_style()
cursor = connection.cursor()
statements, pending = sql.sql_model_create(model, style)
for sql in statements:
cursor.execute(sql)

How can I list app engine datastore parent values with python?

Not sure if on the title I should have said parent values or ancestors, but here is what I am trying to do.
I am learning to use Python in Google App Engine. While I am reviewing the content of this page in the Guestbook tutorial, I was wondering if I could enhance it by listing all possible guestbooks created.
To give a bit of context, this is how the sample code works. The application renders a page that allows you to create a guestbook entry, as well as switching/creating new guestbooks for current or future entries. I thought it would be simple to add the ability to list all currently stored guestbooks to dynamically generate a list of links to see each one.
I thought this was very simple, but I am trying and I can't figure it out. How do I query the datastore to give me a list of all the "guestbooks" available so I can build the links dynamically? If the guestbook is called guestbook_2 the url looks like this "?guestbook_name=guestbook_2".
Here is the code of the application (I added the string "INSERT LIST HERE" where I want to addd the list of links I just mentioned):
import cgi
import urllib
from google.appengine.api import users
from google.appengine.ext import ndb
import webapp2
MAIN_PAGE_FOOTER_TEMPLATE = """\
<form action="/sign?%s" method="post">
<div><textarea name="content" rows="3" cols="60"></textarea></div>
<div><input type="submit" value="Sign Guestbook"></div>
</form>
<hr>
<form>Guestbook name (you can create your own guestbook here):
<input value="%s" name="guestbook_name">
<input type="submit" value="switch">
</form>
%s
<br><br>
List of guestbooks: %s
</body>
</html>
"""
DEFAULT_GUESTBOOK_NAME = 'default_guestbook'
# We set a parent key on the 'Greetings' to ensure that they are all in the same
# entity group. Queries across the single entity group will be consistent.
# However, the write rate should be limited to ~1/second.
def guestbook_key(guestbook_name=DEFAULT_GUESTBOOK_NAME):
"""Constructs a Datastore key for a Guestbook entity with guestbook_name."""
return ndb.Key('Guestbook', guestbook_name)
class Greeting(ndb.Model):
"""Models an individual Guestbook entry with author, content, and date."""
author = ndb.UserProperty()
content = ndb.StringProperty(indexed=False)
date = ndb.DateTimeProperty(auto_now_add=True)
class MainPage(webapp2.RequestHandler):
def get(self):
self.response.write('<html><body>')
guestbook_name = self.request.get('guestbook_name',
DEFAULT_GUESTBOOK_NAME)
# Ancestor Queries, as shown here, are strongly consistent with the High
# Replication Datastore. Queries that span entity groups are eventually
# consistent. If we omitted the ancestor from this query there would be
# a slight chance that Greeting that had just been written would not
# show up in a query.
greetings_query = Greeting.query(
ancestor=guestbook_key(guestbook_name)).order(-Greeting.date)
greetings = greetings_query.fetch(10)
for greeting in greetings:
if greeting.author:
self.response.write(
'<b>%s</b> wrote:' % greeting.author.nickname())
else:
self.response.write('An anonymous person wrote:')
self.response.write('<blockquote>%s</blockquote>' %
cgi.escape(greeting.content))
if users.get_current_user():
url = users.create_logout_url(self.request.uri)
url_linktext = 'Logout'
else:
url = users.create_login_url(self.request.uri)
url_linktext = 'Login'
# Write the submission form and the footer of the page
sign_query_params = urllib.urlencode({'guestbook_name': guestbook_name})
self.response.write(MAIN_PAGE_FOOTER_TEMPLATE %
(sign_query_params,
cgi.escape(guestbook_name),
url,
url_linktext,
"INSERT LIST HERE"
))
class Guestbook(webapp2.RequestHandler):
def post(self):
# We set the same parent key on the 'Greeting' to ensure each Greeting
# is in the same entity group. Queries across the single entity group
# will be consistent. However, the write rate to a single entity group
# should be limited to ~1/second.
guestbook_name = self.request.get('guestbook_name',
DEFAULT_GUESTBOOK_NAME)
greeting = Greeting(parent=guestbook_key(guestbook_name))
if users.get_current_user():
greeting.author = users.get_current_user()
greeting.content = self.request.get('content')
greeting.put()
query_params = {'guestbook_name': guestbook_name}
self.redirect('/?' + urllib.urlencode(query_params))
application = webapp2.WSGIApplication([
('/', MainPage),
('/sign', Guestbook),
], debug=True)
Just store the guestbook name somewhere, or the easiest thing is you can fetch all the Greeting's key to get the parent, something like
guestbooks = [greeting.key().parent().name() for greeting in Greeting.all(keys_only=True)]

django How do I get the user id in the data base with a foreign key

I'd like to get the user id in the db automatically when the user fill a form, but I don't know what I have to do. I'm working on that for all day long, I tried to do it by an hidden input but I'm not it's the solution.
This is my code:
class ImputationForm(forms.Form):
user = forms.ModelChoiceField(queryset=User.objects.all(), widget=forms.HiddenInput())
morning = forms.BooleanField( required=False)
afternoon = forms.BooleanField(required=False)
workpackage = forms.ModelChoiceField(
queryset=Workpackage.objects.all()
)
class ImputationFormModel(ModelForm):
class Meta:
model = Imputation
def imputation(request):
if request.method == 'POST': # If the form has been submitted...
form = ImputationForm(request.POST) # A form bound to the POST data
f = ImputationFormModel(request.POST)
if form.is_valid(): # All validation rules pass
user = request.user.id
morning = form.cleaned_data['morning']
afternoon = form.cleaned_data['afternoon']
workpackage = form.cleaned_data['workpackage']
f.save()
return render_to_response( 'no/form.html', {'form' : form, }, context_instance=RequestContext(request))
else:
form = ImputationForm()
return render_to_response( 'no/form.html', {'form' : form, }, context_instance=RequestContext(request))
Great question. Let's first start by identifying the purpose of various lines of code of your application and see if we can make sense of it. I see that you've got two forms right now which seems to reference the same kinds of data, which is a bit redundant. We'll want to avoid redundancy where possible, so let's start by perhaps cleaning up the code.
We can tell by the code you've shared that you're trying to:
Allow a user to submit a form with data regarding "morning", "afternoon", and "workpackage".
We're not checking whether or not you're editing an instance, so we can assume that upon successful form submission, a new Imputation record is created in the database with the data passed into it.
You're asking for a hidden input of a user value on the client side, which binds the submitted user ID to the form for adding a relationship with the user to the newly saved Imputation record.
Generally, you never want to allow hidden variables regarding sensitive or personal data that can be associated with a user on the client side. It's considered a huge security risk. A user may edit the hidden field using Firebug (or other DOM editing tools) and bind the user ID to a different user than which is intended.
With that being said, let's have a gander at the code now:
class ImputationForm(ModelForm):
class Meta:
model = Imputation
fields = [
'morning',
'afternoon',
'workpackage'
]
# assumed fields of morning, afternoon, workpackage
def imputation(request):
if request.method == 'POST': # If the form has been submitted...
form = ImputationForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
form.user = request.user
form.save()
return render_to_response( 'no/form.html', {'form' : form, }, context_instance=RequestContext(request))
else:
form = ImputationForm()
return render_to_response( 'no/form.html', {'form' : form, }, context_instance=RequestContext(request))
With this code, we're no longer asking the user what his ID is on the form, and we're no longer even asking for it in the form altogether. We're allowing Django to determine what the current user ID is and pass it into the model right before saving the form. You'll want to make sure that the user field is set to null=True, blank=True on the model to avoid an exception from being raised.
I hope this helps answer your question.
I found it I'm really a newbie in django sorry for disturbing you and thank you very much for your help I would have not change my way of thinking on this issue without you!!!!! here is what I changed:
def imputation(request):
if request.method == 'POST': # If the form has been submitted...
form = ImputationForm(request.POST) # A form bound to the POST data
if form.is_valid(): # All validation rules pass
#print("%s" % form.user)
print("%s" % form)
new = form.save(commit=False) #here
new.user = request.user #here
new.save() #here
Thanks again ;)

Storing lists of words in database - best practice

I'm implementing a user filter system on a website. Users are to be able to select 'categories' and 'packages' of interest to them and have the matching data presented when they log in. Both sets of data will come from HTML select forms eg. Categories: 'null pointers', 'dead code'... and packages 'package_x', 'package_y', 'package_z'...
My question is about the best way to store this list information in a database (I am using Django and PostgresSQL).
My initial thought is to have a table like this:
user_id - one to one field
categories - textfield - store json data
packages - textfield - store json data
Is there a better way to be doing this?
I would go the route of using a user profile with categories and packages being many to many fields.
In models.py
from django.contrib.auth.models import User
class Category(models.Model):
name = models.CharField(max_length=255)
class Package(models.Model):
name = models.CharField(max_length=255)
class UserProfile(models.Model):
user = models.ForiegnKey(User)
categories = models.ManyToManyField(Category)
packages = models.ManyToManyField(Package)
In admin.py
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.models import User
class CustomUserAdmin(UserAdmin):
inlines = [UserProfile]
#filter_horizontal = ('',) #Makes the selection a bit more friendly
admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
In views.py
user_with_profile = User.objects.get(pk=user_id).get_profile()
All that being said. Django 1.5 will replace the user profile with being able to use a configurable user model.

Google App Engine + Validation

I am looking for how to do validation on Google App Engine and I have found only how to do it using Django framework. Ok Django approach is ok but if I have one form and this form have data from few tables what then???
I can not do it like this:
class Item(db.Model):
name = db.StringProperty()
quantity = db.IntegerProperty(default=1)
target_price = db.FloatProperty()
priority = db.StringProperty(default='Medium',choices=[
'High', 'Medium', 'Low'])
entry_time = db.DateTimeProperty(auto_now_add=True)
added_by = db.UserProperty()
class ItemForm(djangoforms.ModelForm):
class Meta:
model = Item
exclude = ['added_by']
class MainPage(webapp.RequestHandler):
def get(self):
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/">'
'<table>')
# This generates our shopping list form and writes it in the response
self.response.out.write(ItemForm())
self.response.out.write('</table>'
'<input type="submit">'
'</form></body></html>')
def post(self):
data = ItemForm(data=self.request.POST)
if data.is_valid():
# Save the data, and redirect to the view page
entity = data.save(commit=False)
entity.added_by = users.get_current_user()
entity.put()
self.redirect('/items.html')
else:
# Reprint the form
self.response.out.write('<html><body>'
'<form method="POST" '
'action="/">'
'<table>')
self.response.out.write(data)
self.response.out.write('</table>'
'<input type="submit">'
'</form></body></html>')
Is any easy way to validate form which contain data from few tables or I have to code it alone?
Looks like you're using webapp; I suggest your look at some other 'light-weight' choices for form validation. Pick one that you like the layout / syntax of. You'll be able to define complex 'nested' relationships if needed.
FormEncode
Formish
Deform
WTForms has a GAE component WTForms
WTForms now includes support for AppEngine fields as well as auto-form generation. The form class can be used as it is or serve as a base for extended form classes, which can then mix non-model related fields, subforms with other model forms, among other possibilities.

Resources