I am a bit new to GAE, so I wanted to ask, how do you create a user model for something as trivial as a blog.
So, far, this is all I got:
class User(db.Model): # Todo create a user model, that works with your login page
username = db.UserProperty()
password = db.StringProperty()
But this looks very primitive. How would one go about creating a user in google app engine, as in what is the best practice, of creating such fields where uniqueness is an important factor.
Also, how would you link a user to a blog post, since links are not allowed in google data-store.
Finally is there an app that manages all your migrations? Like south for GAE? There seems to be a way to migrate, but it involved a great deal of boiler-plate code.
Also, I come from a django background, so I am finding all of this a little counter-intuitive, since this is not a relational database.
Your User class is fine for now, you can add fields to your model as you need them during development. But you should use ndb rather than db. ndb handles much more features (like automatic caching). You can find more details in the documentation.
If you want to learn more advanced user or datastore models, you can look at gae-boilerplate, which already handles user login and signup (even from facebook/twitter/...). The README is very well documented :
https://github.com/coto/gae-boilerplate
You can implement some kind of relations in your models, either by using a KeyProperty() or by setting a parent entity when you create one. For example :
class BlogPost(ndb.Model):
title = ndb.StringProperty()
content = ndb.TextProperty()
timestamp = ndb.DateTimeProperty(auto_add_now=True)
# Then you can specify a parent in the constructor (where user is a User entity)
blog_post = BlogPost(parent=user)
blog_post.title = 'Post title'
blog_post.content = 'Post content'
blog_post.put()
Then use Ancestor queries to retrieve all blog posts published by a user.
Related
I have a NOTIFICATION and an USER app in Django.
The code goes something like :
class Notification(models.Model):
user = models.ForeignKey(User , related_name = "notification"
....
....
and
class User(models.Model):
notifications = models.OneToManyField(Notification , related_name = "user"
....
....
Now I know that models.OneToManyField doesn't exist in Django.
I get the fact that I can simply access the user from the notification instance of the model. But I suppose that would somehow slow my system because in production I would keep all the instances of Notification Model.
For example : I'm expecting around 500+ notifications per user once the system is in production for a significant amount of time.
I suppose, it would just be easier to access all the notifications of one user directly rather than sifting through the whole Notification Table to find notifications of a specific user.
I've read this and the documentation to an extent and I'm not able to find a solution to my problem.
Also I'm not sure about the processing constraints of a processor to obtain all the Notifications from the whole Notification Table. I'm just assuming that it'll be somewhat slower.
OneToManyField doesn't exist in Django because it is just the reverse relationship of a ForeignKey. So you don't need the notifications field on the User model here, just remove it.
Don't worry prematurely about performance of filtering on the notifications. Querying relations is what SQL was designed for, and that's what relational databases are good at doing.
While searching online on how to accomplish custom authentication in Django I came across this and this article. Both of these articles specified the same instructions. Currently i have something like this. (Taken from first article)
class Client(models.Model):
email = models.EmailField(unique=True, max_length=100)
password = models.CharField(max_length=128)
Then in another python file I have this
from .models import Client
class ClientAuthBackend(object):
def authenticate(self, username=None, password=None):
try:
user = Client.objects.get(email=username)
return user
if password == 'master':
# Authentication success by returning the user
return user
else:
# Authentication fails if None is returned
return None
except Client.DoesNotExist:
return None
def get_user(self, user_id):
try:
return Client.objects.get(pk=user_id)
except Client.DoesNotExist:
return None
I just started using Django and have kind of skipped the model section for db interaction since in my current project I am using RAW and custom SQL due to certain reasons.
My question is where does the
user = Client.objects.get(email=username)
get its user from . Do I have to make an entry into a database ?
What I want to do is to create a user during runtime and not save to the database.I tried doing this
#The following creates and saves a user in the db
u =User.objects.create_user('john', 'lennon#thebeatles.com', 'johnpassword',cust_address="my_custom_address",cust_msg="Users custom message")
The above returns a Client.DoesNotExist exception.
My question is where does the
user = Client.objects.get(email=username)
get its user from
Apparently, Client is a models.Model. This means that represents a single record of the relevant table in your database, wherever that is depending on the relevant settings.py setting.
Therefore, the table representing that model can be created with the next Django migration and lots of other useful things Django allows for.
So essentialy the above statement instructs the Django ORM to fetch all Client records from that particular table with that specific email. If no such entries exist, none will be returned.
I tried doing this
u =User.objects.create_user('john', 'lennon#thebeatles.com', 'johnpassword',cust_address="my_custom_address",cust_msg="Users custom message")
This is where you complicate things a bit. The create_user method is not part of Django ORM, but part of the Django default auth model manager django.contrib.auth.models.User. You should either provide such a method yourself, or easier to just use the standard create method provided with the default Django model manager.
Not saving the user model even on some cache does not make sense at all, as it implies that the user registers each time he or she wishes to login.
Having said all those, I would strongly recommend you to read the official Django documentation. All the above are covered, the documentation is very comprehensive and not that long. You can then read and understand tutorials on the wild which may or may not be correct or up to date.
Take a good read specifically on the Customizing authentication topic, as it provides additional methods far easier for the beginner.
A great greetings community
My question is related with the kind of manage users and the schema users in Django, In beginning I ask to you apologize just in case that my questions can will be too "newbies" or without sense, I am starting to related me with the Django Users schemas and their different possibilities of work in the projects.
I have the following situation.
I am building an application in which I will have three differents user types:
Medical
Patient
Physiotherapist
I am using the default Django authentication scheme (django.contrib.auth).
Initially, I did think in this scheme of entities in which the User table is the auth_user table in where Django save the users created:
I have the is_patient, is_medical and is_physiotherapist fields like boolean attributes in the User table.
Like a particular detail I understand that in the Django default model User is not possible modify or add attributes or fields.
This is an important and powerful reason to I cannot add the is_patient, is_medical and is_physiotherapist boolean fields in User table.
A classic recommendation is extend the User model with a Userprofile table in which I add fields or attributes to User Model through of OneToOne relationship. A basic sample is such as follow:
Is of this way that I get that my users in Django can have the field photo and upload one in a given moment ...
Taking advantage of the previous,
The following schema can be suited or can be an alternative for manage user roles (patient, medical and physiotherapist user types) ?
I will have relationships between:
User medical and user patients
user physiotherapist and user patients
and so between them and other tables ...
With this approach these relationships don't will be affected?
The different users will be saved between the Users and UserProfile table.
Is this a good practice in the scalability sense? My tables could be crash or my database?
In addition, I also have seen other alternatives such as:
Role Table/Model
I will have a role table/model independent or separate and that this can be related with the Django User model (One User can will have many roles by example)
This approach can be useful when I want store exclusive information about of a role in specia?
Django Permissions and Authorization
I ignore or unknown the granularity grade that let will me work. Of a single way I have been see that the permissions and authorizations system let will me work with create and edit and remove operations ....
Here, can I see the groups creation?
For example a medical group and allocate them permissions and linked this permissions to the users that compose the group ? Is this another good alternative?
This option seem more single although I don't know if an user could make some operations according to the group privileges that have ... I don't know if this thinking is correct/right
AUTH_USER_MODEL Creating a Custom User model
My requirements for patient, medical and physiotherapist users, require build a custom user model?
In this situation, especially if you want to store different infos for Patients, Medics and Physiotherapists you can create a Model for each and have a OneToOne field for each to the User model.
class Medic(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
class Physio(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
class Patient(models.Model):
user = models.OneToOneField(User, primary_key=True)
# other fields
This way you can give different permissions/roles implicitly in your application logic for each type of user (and still use the groups and permissions that Django offers if you need them for special cases, eg ChiefMedical...).
You will have to define some methods for your application logic like
def user_is_patient(user):
...
If you follow this path it is a good idea to have good tests to make sure that you don't get unexpected things like a user who is a Medic and a Physio...
Django lets you subclass the user model as well. Under the covers it would do the same thing as the code above, so it is probably better to do it explicitly as shown above (this way it is less probable that you access attributes that don't exist in that object!)
Taking advantage of the previous, The following schema can be suited or can be an alternative for manage user roles (patient, medical and physiotherapist user types) ?
The schema you show isn't great because it makes you store the information for all user types in the same table (and with the same fields). For example, Medics and Physios will have a blood type field type like Patients which will probably not be defined.
The different users will be saved between the Users and UserProfile table. Is this a good practice in the scalability sense? My tables could be crash or my database?
There should be no scalability problems with this solution (as long as you don't have millions new entries writes every day) and you can always optimise the database at a further point. However, you will have to make sure that your app doesn't accept 'forbidden' entries (e.g. users with no Medic, Physio or Patient profile)
Here, can I see the groups creation? For example a medical group and allocate them permissions and linked this permissions to the users that compose the group ? Is this another good alternative? This option seem more single although I don't know if an user could make some operations according to the group privileges that have ... I don't know if this thinking is correct/right
You can (should) use Django's permission system to give permissions to your users. You can use them to give different rights to users of the same type (for example Medics that have more permissions than others... or have groups for chief physios...)
Django lets you assign permissions to a group.
But I don't think groups can replace the custom models for each user, since you want to store information for them. Having custom models and groups would be redundant and make your app harder to maintain.
My requirements for patient, medical and physiotherapist users, require build a custom user model?
This option wouldn't be great (unless it is your only option) because your app won't be reusable and you might have problems with some packages as well.
You can create a custom User model or not, in any case, you could have three separate models for storing pertinent data, depending on whether the user is patient, medical, physiotherapist, or any combination of these.
If your permissions scheme is determined solely by the role (patient, medical, physiotherapist) then you don't need to use Django's permissions system, because you know the role(s) of any user and you can, in the worst scenario, hardcode authorization rules.
I gave a glance at question's comments and I view some issues:
()
I realized that your user model does not match with the original data model since having get_medical_profile, get_patient_profile and get_physiotherapist_profile functions inside user model, with that you are assuming that any user could have multiple profiles at the same time, which isn't reflected neither in your profile models (Medical, Patient and Physiotherapist) using OneToOneField nor in original data model of the question, it's an important thing about abstraction and class-responsibility. The requirement (according the model below) seems to say "one user can have only one profile".
So.. I think this can be solved in a straightforward and clean way, you don't need to involve in overall authentication esquema like groups and permissions or adding additional attributes to user model:
class UserProfile(models.Model):
user = models.OneToOneField(User)
# common fields shared by medical, patient and physiotherapist profiles
class MedicalUser(models.Model):
profile = models.OneToOneField(UserProfile)
# medical fields here
class PatientUser(models.Model):
profile = models.OneToOneField(UserProfile)
# patient fields here
class PhysiotherapistUser(models.Model):
profile = models.ForeignKey(UserProfile)
# patient fields here
As you see, you can have a profile which contains common fields shared by all profiles. and each profile has an specific model.
In addition, you can check if user is medical by this small function below, then if there is no an medical profile associated with profile then it will raise exception and it means it's a profile unspecified:
def is_medical_profile(profile):
try:
profile.medical_user
return True
except:
return False
You can also use it in your templates (as a custom template tag) in this way:
{% if profile | is_medical_profile %}
With this approach you don't need to setup AUTH_USER_MODEL
I hope this improves your solution.
Additional notes:
Just in case you decide to have a custom user model, setup settings.AUTH_USER_MODEL and use it for foreign keys to User.
On a piece of text of awesome book Two scoops of Django says:
From Django 1.5 onwards, the official preferred way to attach
ForeignKey, OneToOneField, or ManyToManyField to User
Therefore, your user profile model would change as follows:
from django.conf import settings
from django.db import models
class UserProfile(models.Model):
user = models.OneToOneField(settings.AUTH_USER_MODEL)
Yes, it looks a bit strange, but that's what the official Django docs advice.
#geoom #Ire #lorenzo-peña I 've created an user through Django admin site and I checked their attributes (is_medical, is_patient, is_physiotherapist) via python shell
In [6]: User.objects.filter(username='agarcial').values('is_medical','is_patient','is_physiotherapist')
Out[6]: [{'is_physiotherapist': True, 'is_patient': True, 'is_medical': True}]
For the moment in my views.py I am doing that an user sign in only when this be one of three user types (medical, patient or physiotherapist)
# Create your views here.
class ProfileView(LoginRequiredMixin, TemplateView):
template_name = 'profile.html'
def get_context_data(self, **kwargs):
self.request.session['Hi'] = True
context = super(ProfileView, self).get_context_data(**kwargs)
is_auth = False
name = None
# Check if in the request goes the user
user = self.request.user
# Check about of possible cases (For now is one profile)
if user.is_medical:
#if self.request.user.is_authenticated():
print (user.is_medical)
is_auth = True
profile=user.get_medical_profile()
#name = self.request.user.username
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile, 'data':data})
elif user.is_patient:
print (user.is_patient)
is_auth=True
profile=user.get_patient_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
elif user.is_physiotherapist:
print (user.is_physiotherapist)
is_auth=True
profile=user.get_physiotherapist_profile()
data = {
'is_auth':is_auth,
'profile':profile,
}
context.update({'userprofile':profile,'data':data})
return context
def get_userprofile(self):
return self.request.user.userprofile
If I check the other possible combinations (User patient,medical and physiotherapist) this could work?
I think create groups for (Medicals, Patients, Physiotherapists) and binding users for the authorization topic, although I should review other things for authorization process such as django guardian for example?
How about this?
I'll start by saying that my database skills are weak, and it's quite possible I'm just designing this wrong.
I'm working on a Django 1.3 application that would allow customers to log in to view various aspects of their "account". One of the models is "Customer", and it makes sense to me that I add a field in that model for "username" so that I can show projects, payments etc that belong to each customer.
I've got much of my schema set up but I can't figure out how to make a "username" field that references the django login name. You average field looks something like
projects = models.ManyToManyField('Project')
website = models.URLField()
updates to clarify
what I think I need is:
username = models.ForeignKey(WhereverDjangoKeepsTheUserModel)
SOLVED
I needed
from django.contrib.auth.models import User
and
username = models.ForeignKey(User)
Accepting Jack M's answer because it helped me find the specific piece I needed.
You are probably looking for a ForeignKey relationship.
projects = models.ManyToManyField('Project')
website = models.URLField()
user = models.ForeignKey('User')
Then from within your view:
project = Project.objects.all()[0]
username = project.user.username ## Or whatever you want to do with it.
To read more about this, check out the "Your First Model" section in chapter 5 of The Django Book.
I just got done working through the Django tutorials for the second time, and am understanding things much more clearly now. However, I'm still unclear how apps inside a site interact with one another.
For example, lets say I'm writing a blog application (a rather popular activity, apparently). Blog posts and comments tend to go together, and yet they are distinct enough that they should be built into separate apps, as is the general philosophy of Djano development.
Consider the following example. In reality I would not actually write the comment app myself, as good code for that already exists on the web, but this is for demonstration/practice purposes:
mysite/blog/models.py
from django.db import models
class post(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=200)
content = models.TextField()
mysite/comments/models.py
from django.db import models
from mysite.blog.models import post
class comment(models.Model):
id = models.AutoField()
post = models.ForeignKey(post)
author = models.CharField(max_length=200)
text = models.TextField()
Is what I wrote above, importing a model from another app and setting it as a foreign key, how Django apps interact? Or is there a different/better method for the apps that comprise a site to interact?
Update
Per the recommendation in one response, I'm reading the documentation for contrib.contenttypes. If I'm reading this correctly, I could rewrite my example comment app like this:
from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contentypes import generic
class comment(models.Model):
id = models.AutoField()
author = models.CharField(max_length=200)
text = models.TextField()
content_type = models.ForeignKey(ContentType)
content_object = generic.GenericForeignKey(content_type, id)
Would this be correct?
Take a look at django's built-in contenttypes framework:
django.contrib.contenttypes
It allows you develop your applications as stand-alone units. This is what the django developers used to allow django's built-in comment framework to attach a comment to any model in your project.
For instance, if you have some content object that you want to "attach" to other content objects of different types, like allowing each user to leave a "favorite" star on a blog post, image, or user profile, you can create a Favorite model with a generic relation field like so:
from django.db import models
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic
class Favorite(models.Model):
user = models.ForeignKey(User)
content_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
content_object = generic.GenericForeignKey('content_type', 'object_id')
In this way you can add a Favorite star from any user to any model in your project. If you want to add API access via the recipient model class you can either add a reverse generic relation field on the recipient model (although this would be "coupling" the two models, which you said you wanted to avoid), or do the lookup through the Favorite model with the content_type and object_id of the recipient instance, see the official docs for an example.
"Is what I wrote above, importing a model from another app and setting it as a foreign key, how Django apps interact?"
Yep. Works for me.
We have about 10 applications that borrow back and forth among themselves.
This leads to a kind of dependency in our unit test script.
It looks like this.
"ownership". We have a simple data ownership application that defines some core ownership concepts that other applications depend on. There are a few simple tables here.
"thing". [Not the real name]. Our thing application has data elements owned by different user groups. There are actually several complex tables the model for this app. It depends on "ownership".
"tables". [Not the real name]. Some of our users create fairly complex off-line models (probably with spreadsheets) and upload the results of that modeling in "tables". This has a cluster of fairly complex tables. It depends on "ownership".
"result". [Not the real name]. Our results are based on things which have owners. The results are based on things and tables, and are responses to customer requests. This isn't too complex, perhaps only two or three core tables. It depends on "things" and "table". No, it doesn't completely stand-alone. However, it is subject to more change than the other things on which it depends. That's why it's separate.
"processing". We schedule and monitor big batch jobs. This is in this application. It's really generic, and can be used in a variety of ways. It completely stands alone.
"welcome". We have a "welcome" app that presents a bunch of mostly static pages. This doesn't have too many tables. But it's on it's second incarnation because the first was too complex. It completely stands alone.
The only relationship among the dependent apps is some table names. As long as we preserve those tables (and their keys) we can rearrange other apps as we see fit.
There's nothing wrong (imho) with making some app dependent on another. After all, apps are just operations on a set of models. you just have to always be aware of which app depends on which app (I guess you could call that a dependency map).
You can achieve loose coupling with the contenttypes framework. It allows an app to be truely portable/pluggable yet still integrated with other applications.
I wrote a comments app (yea, I re-invented the wheel), that can be integrated into any other application, with a few lines in the template of the page where comments should be posted (using custom tags).
Say you want a model "thread" to be pluggable into any other model. The idea is to create e generic foreign key (see django documentation on that), and write a small function that takes any object and returns a "thread" corresponding to it (or creates one if necessary), and write a custom template tag that uses that functionality, e.g. {% get_thread for arbitrary_object as thread %}. All posts are related to a thread, which is related to the object, which can be of any type.
You can think of the "thread" object as a kind of a proxy, so instead of having a post be related to a certain "article" or a "blog post", it's just related to a thread, which is abstract in a sense, what is is a thread? It's just a collection of posts. The thread then allows itself to be related to any object regardless of its type. (although it does more than that, it could hold extra information such as allowing/disallowing anon. posts, closing/opening comments on the page, etc ..)
EDIT
Here's how you can create a generic foreign key with the content types framework:
from django.contrib.contenttypes import generic
from django.contrib.contenttypes.models import ContentType
class Thread( models.Model ):
object_type = models.ForeignKey(ContentType)
object_id = models.PositiveIntegerField()
object = generic.GenericForeignKey('object_type', 'object_id')
You can make it more "transparent" by exploiting the implicit "common" interface that django assumes all objects implement ..
#inside the Thread class:
def __unicode__(self):
return unicode(self.object)
def get_absolute_url(self):
return self.object.get_absolute_url()
Your code seems correct. I would keep the post and the comment in a blog app though. I am not saying this is the Django way, but those models are close enough to be in the same app.
How To Divide The Project
I would seperate an app if;
I plan to design it resuable. (and try loose coupling)
(for big projects) It consists of a major section of the project.
On the other hand; having many tiny apps (such as an app with a single model and two views) is hard to read and maintain IMHO.
How Apps Should Interact
This depends on the type of project and the type of the app again. For example if an app is implicitly dependent on another (ie not generic) importing and using references from the other app is acceptable. In this case the second app might be installed alone, but the first one needs the presence of the second.
If you want to make an app highly reusable and generic, such as a commenting app, you might need to integrate some setup mechanism. Maybe some new settings or additional URL configuration, or a special directive/method on your models... django.contrib.admin is a good example for this.
Apps shouldn't interact if it is not necessary though. Designing apps to avoid unnecessary coupling is very useful. It improves your app's flexibility and makes it more maintainable (but possibly with a higher cost in integrating).