Django sites framework permissions - django

I am using the sites framework to run multiple apps off of one code base. I have 3 users, and 3 sites. They can login to the django admin interface and create content but I want them to see only the site they are allowed to manage, not the others, can the sites framework handle this? if not can anyone guide me to the right direction as to how this can be accomplished?
EDIT:
What I did was a simple example. Here goes....
class Weblog(models.Model):
title = models.CharField(max_length=250)
slug = models.SlugField(unique=True)
user = models.ForeignKey(User) # this is the user who should own that blog and see nothing else
site = models.ForeignKey(Site)
objects = models.Manager()
on_site = CurrentSiteManager()
def __unicode__(self):
return self.title
class Entry(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField()
body = models.TextField()
author = models.ForeignKey(User)
weblog = models.ForeignKey(Weblog)
This is where I am confused. I understand the concept of a weblog having a reference to a site and a user as well. But then how does one limit that person to only see and add/edit the entries on their own weblog that was created for them?
Thanks

Yes, the Django sites framework can do exactly that. As I have not much information about what you already did, I can't really help you, so please give more details.
Also check the specific documentation.
EDIT Ok, I understand it now, your problem is to restrict users to only view and edit content about their dedicated site. This is a little more complicated.
It depends if you use the admin interface or custom views to handle this views and edits. If you use custom ones it can be done easily changing the queryset used, but I imagine you use the admin interface.
In this case, maybe overriding the default manager (objects) with CurrentSiteManager() can do the job. But
it can have side effects, overriding the default manager is not recommended, you need to test it (the first side effect is: you won't have a listing of all edits on all sites)
you must be sure that user A can't login in site B admin interface
Another solution may be to create custom admins for each one of these websites. See the admin doc.
But, just a question: if you don't want to let users edit content on each of these websites, do you however need to have a unique interface to all this admin websites? For example to let one person be able to edit content on all the sites)
If not, maybe the Sites framework is not the way to go, and you should better make each website independant and clearly separated?
Another solution is to look to the permissions possibilities of Django which let you define custom permissions to your views. I think (haven't tried it) it can also be used to protect admin views.
I hope this can help.

Django-site-permissions application would do exactly that:
https://github.com/bmihelac/django-site-permissions
You can integrate it in your project if it meets your needs or check the source code to see how site wide permissions can be implemented.
(disclaimer: I am the developer of django-site-permissions app)

Related

django-rest-framework, third-party javascript app registration and creating new thread

I have created a forum project something similar to these with Forum model,Category model, thread model, comment model, user model, Notification model. I exposed these model through rest-framework with ForumSerializer, CategorySerializer and such. In api viewsets I have viewsets similar to this:
class CategoryViewSet(viewsets.ModelViewSet):
queryset = Category.objects.all()
serializer_class = CategorySerializer
It works .yay!
I worked on to make it something similar to what disqus offers. A 3rd party comments hosting site. I worked with third party javascript and created a javascript snippet that can be embeded on other sites. I installed django-cors-headers and enabled Cross-origin resource sharing.
Here comes my question. If a user registers a website and uses javascript snippet, I need to create a new thread using the headline and other unique identifiers. I figured how disqus does this. (Q1) What is/are the best practices to do this type of registration. Providing a api key(secret and public) or any other?
f ----->forum,
t_i----> identifier,
t_u----> url
t_s----> slug,
t_e----> title,
t_d----> documentTitle,
t_t----> title || documentTitle,
t_c ---->category,
s_o----> sortOrder,
l----> language
Disqus creates a new thread and serves the comment section at something like this, which is embeded in an iframe
Example url:
https://example.com/embed/comments/?base=default&
version=edb619270a92c3035c453faa7c9444d1&
f=example&
t_i=article_2431522&
t_u=http%3A%2F%2Fwww.example.com%2Fhollywood%2Flatest-trailer-of-spectre-is-out-james-bond-is-back-all-guns-and-cars-blazing-2431522.html%09&
t_e=Latest%20trailer%20of%20%27Spectre%27%20is%20out%3A%20James%20Bond%20is%20back%20all%20guns%20and%20cars%20blazing&
t_d=Latest%20trailer%20of%20%27Spectre%27%20is%20out%3A%20James%20Bond%20is%20back%20all%20guns%20and%20cars%20blazing&
t_t=Latest%20trailer%20of%20%27Spectre%27%20is%20out%3A%20James%20Bond%20is%20back%20all%20guns%20and%20cars%20blazing&
s_o=default
(Q2) How to create a new thread and save the above unique identifiers, if it's not already created in django to serve.
Is there any open source or other project I can see to get some reference on how to do it.
I am looking for best practices.
P.S. I do not require code,I would appreciate if provided though. Explained it technical terms with logical steps will do. I'll search.
P.P.S I searched all over github for any open-source projects to see how they implement. Searched 790+ projects with no hits so far.
Thank you very much

Django admin particular data for particular user

I am using django admin site to let people manage database easier.
For some reason, I want to hide some data from some user.
Let's say I have a model named Book and there are a lot of books in database. I want different user has the different scope of books he can view.
How would I do that?
I am thinking about permission. Is that possible to set the permission to filter the data?
I know how to create permission according to a specified model. However, after that, how do I suppose to use that permission? I believe I may need to override part of "changelist_view" method under BookAdmin class, right?
Any help would works.
Thanks in advance
Use the queryset method on your admin model. Something like:
class BookAdmin(admin.ModelAdmin):
def queryset(self, request):
return super(BookAdmin, self).queryset(request).filter(owner=request.user)
Obviously the filter will vary depending on your book model, but this is the general idea.

Adding fields to user's personal info in Django admin page

I just started a Django project (there are no apps in it). I activated the admin in settings file and can access the Django administration page. There is a column in Django page to add users; while adding users I get only three fields under personnal info, but I need to store some more information about users. I Googled around and found that I can use user profiles to accomplish this. I tried, but I am having problems.
My aim is to add three more fields to the user table:
role
contact number
other
I need details like: which function I need to write and where to do this.
I found this, but I do not know where I need to write these steps. I would greatly appreciate a more clear explanation of this.
Django User Profiles is what you need. The blog you linked to has clear steps on how to do it. You can check out the Django documentation. http://www.turnkeylinux.org/blog/django-profile also provides a good explanation.
Basically you need to create a new model with User as ForeignKey and define the model in the settings.py as AUTH_PROFILE_MODULE = "django_app.your_profile_modelname". Create the profile and save it just like any other model, and access it using user.get_profile()
Adding a couple of things in response to your questions below:
First, do not create apps as a directory. Use startapp <appname> [destination] as described here. That will create the app directory.
Second, you have to add the app to INSTALLED_APPS in the project's settings file, do a syncdb. Basically, follow the steps in Django tutorial on writing your first app.
Third, UserProfile is a separate model. It is not an extension of User. It is associated with the User just because you added User as the ForeignKey.
Fourth, to be able to see the user profile model in admin, you do exactly what you would do to add any other model to admin page. Create a file names admin.py under your app with:
from django.contrib import admin
from myproject.app.models import UserProfile
admin.site.register(UserProfile)
There are three key concepts to understand:
There is no built in "profile" system in Django, beyond the limited auth app which is really geared just to user login. You are expected to roll your own.
There is nothing magical about a profile record in itslef, it is just like any other record that takes User as a foreign key (or, more properly, a one-to-one field as per the docs). You create it by creating a custom django app (traditionally called profiles) and a model for that app (traditionally called UserProfile, since Profile is not allowed as a model name).
The only thing that sets UserProfile aparts as a model is that you specify it as the AUTH_PROFILE_MODULE which means that it is accessible when called .get_profile() on a User record. That's it. If you set up the UserProfile like so:
def UserProfile(models.Model):
user = models.OneToOneField(User, related_name='profile')
other fields
then you can also access the profile as user.profile rather than user.get_profile() which some people prefer.
Again, nothing magical about the profile model -- it is just a model record like any other model record.
If you want to be able to edit additional fields within the user form that's more complicated; easiest way is probable unregister User and then register it again using your custom ModelAdmin and form class but judging by your question you're probably not at that level yet.

Django custom User model authentication

Since i'm not using the Auth User from Django, I have my own model CustomUser and I want make authentication on site through this model (CustomUser does not inherit from User model and not related to it at all).
class CustomUser(models.Model):
password = models.CharField(max_length = 40)
email = models.EmailField(max_length = 72, unique = True)
#stuff...
I checked https://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authentication-backend and the main thing I don't understand is:
from django.contrib.auth.models import User
Do I need to import Django User if I want to use my CustomUser?
I can't find a good tutorial which explains how you can use Django without standard Auth User.
*edit:
I know I can extend with User. But I just don't want that. The question is not: what is the best way to use User and store additional information etc etc. I appreciate it though.
BUT how I can use a Custom User without using Auth User. Even if I don't have a reason to. *
If it is possible I want to know how.
The whole Django auth system is tightly coupled with django.contrib.auth.models.User, so you should use it in the backend. Quoting Django docs
For now, the best way to deal with this is to create a Django User object for each user that exists for your backend
But the main question here is: what is so special about your CustomUser that you can't implement with normal User model (may be extended)? In 99% of cases using User is the best way.
Check out this post.
Most of the Django projects I’ve worked on need to store information about each user in addition to the standard name and email address held by the contrib.auth.models.User model.
If you’re using trunk as of revision 7477 (26th April 2008), your model classes can inherit from an existing model class. Additional fields are stored in a separate table which is linked to the table of the base model. When you retrieve your model, the query uses a join to get the fields from it and the base model.
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
And this post.
Copy the auth application over into your own project and modify it to your needs. This avoids some of the maintenance troubles, but removes the utility of Django bundling an auth system in the first place. It can also cause compatibility problems with other applications which expect the User model to be in django.contrib.auth.
http://www.b-list.org/weblog/2006/jun/06/django-tips-extending-user-model/
Perhaps this answers your question:
From 'https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#substituting-a-custom-user-model':
Substituting a custom User model
New in Django 1.5.
Some kinds of projects may have authentication requirements for which Django’s built-in User model is not always appropriate. For instance, on some sites it makes more sense to use an email address as your identification token instead of a username.
Django allows you to override the default User model by providing a value for the AUTH_USER_MODEL setting that references a custom model:
AUTH_USER_MODEL = 'myapp.MyUser'
This dotted pair describes the name of the Django app (which must be in your INSTALLED_APPS), and the name of the Django model that you wish to use as your User model.
Of course there are some requisite warnings to consider (available at the above link), but this is looking like a good answer to your question: https://docs.djangoproject.com/en/1.6/ref/settings/#auth-user-model
There are also some custom model compliance expectations to consider (too many to list here): https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#specifying-a-custom-user-model
Unless there can be more than one value for AUTH_USER_MODEL (I doubt that is sane), then I think I will need to build my own custom authentication backend: https://docs.djangoproject.com/en/1.6/topics/auth/customizing/#writing-an-authentication-backend
I hope this helps any other lost souls out there that need distinct User and Device authentication schemes (perhaps because of some pre-existing spec that makes messy what could be soooo easy).
Cheers!

Project platform suggestion for web application with proper User Auth and integration support

So, I have an idea to build a web app. I am new to this business but am a programmer. I liked Python and thought let me start with Django. I ran into a problem with the built-in Django User Auth system as pointed by this question of mine on SO.
In short, I am using Django's built-in User auth and thought that it will easily fill my user field (the foreignkey) in my model but it does not. I have Googled and asked questions but only got a very convoluted answer or that I have to use the Admin section if I want anything like that.
My simple need is that whenever user saves anything in their profile, the user field should get populated so that I can reference it. To me, it sounds like the most basic need for any web app.
Am I wrong. I need advice. If Django is not good for this then I am ready to learn any other good framework or platform if need be.
In short, I am using Django's built-in
User auth and thought that it will
easily fill my user field (the
foreignkey) in my model but it does
not.
This won't just magically happen. You will have make it happen. Models are separated from the request so this would happen in your view, or a model method (perhaps save) that is passed the active user.
MVC / MTV design separates the database from the view / control logic. I don't see what framework has to do with this: unless you write the functionality yourself, the database doesn't know what to do with some User table and the currently logged in user (also separated from the data). Building in this functionality would inconvenience a lot of people as well...
In general, the python/django philosophy is: Explicit is better than implicit.
Now the solutions:
If you wanted this behavior in the view, for any form, you could potentially write:
instance = MyForm.save(commit=False) # commit=False prevents DB save.
instance.user = request.user
instance.save()
You could overwrite the save method on the model that accepts an optional user argument as well.
def save(self, *args, **kwargs):
user = kwargs.pop(user, None)
self.user = user
super(MyModel, self).save(*args, **kwargs)
mymodel = MyModel()
mymodel.save(user=request.user)