django share document with user - django

I have a my django site where admin user will have to share documents with other user type called accountant.for example admin has something called documents in the sidebar when clicked it shows the list of documents related to the admin beside every document we will have a button share when clicked it shows the list of accountants when selected and shared the documents will be listed on the accountant's documents list page.there are two different login interfaces.how can i achieve this i have model called Document and the user type model Accountant.how should the relations should be and what should be the logic in views.
class Document(models.Model):
name = models.Charfield()
file = model.Filefield()
class Accountant(models.Model):
name = models.Charfield()

your question is general you have to ask more specifically where exactly your problem is.
I guess you dint know how the relationship between models is going.
you can use many-to-many relationships to solve your problem.
something like this:
class Document(models.Model):
name = models.Charfield()
file = model.Filefield()
has_access_to = models.ManyToManyField(Accountant)
add like this:
# document_instance is a document object and accountant instace is the same
document_instance.has_access_to.add(accountant_instance)
for showing use this :
accountant_instance.document.all()
I hope this helps you.

Related

Django Admin not limiting choices on ManyToMany field

I suddenly am having a problem with my django admin panel.
I have the following models:
class Role(models.Model):
name = models.CharField("Name", max_length=32)
class Person(models.Model):
name = models.CharField("Name", max_length=64)
role = models.ForeignKey(Role)
class Team(models.Model):
rep = models.ManyToManyField(
Person,
related_name="rep_on",
limit_choices_to={'role__name': 'Sales Rep'})
eng = models.ManyToManyField(
Person,
related_name="eng_on",
limit_choices_to={'role_id__name': "Engineer"})
(The two options in the limit_choices_to dictionaries are the two methods I've tried. In the past it seemed like role_id__name worked, but now it doesn't.)
If I create roles for the Sales Rep and Engineer, and create a bunch of people and attach roles, when I create a Team in the admin, I get dropdowns like I expect:
There are two problems. Each dropdown contains every Person object, so limit_choices_to doesn't seem to work at all, and of course these relationships are generic "TEAM-PERSON RELATIONSHIPS" and I'd like to be able to at least label those correctly.
I swear this worked before, and now it's not working. Any ideas as to what could be causing this?
EDIT:
I created a toy application to explore this and tried to slowly recreate the full issue. In my real app I am using two Inlines in the admin interface for the Team object and excluding the model fields. I added them into my test code and managed to recreate the issue.
class RepInline(admin.TabularInline):
model = Team.rep.through
class EngInline(admin.TabularInline):
model = Team.eng.through
class TeamAdmin(admin.ModelAdmin):
inlines = [RepInline, EngInline]
admin.site.register(Role)
admin.site.register(Person)
admin.site.register(Team, TeamAdmin)
And my admin screen looks like:
The given HTML Select fields are filtered, but the dropdowns are not, So the issue lies in the TabularInline, so I have to decide if I want to keep them or not.

Django: How to create an instance of a list of multiple objects and display on admin page

So say for example, I have a model Student:
class product(models.Model):
name = models.CharField(max_length=200)
description = models.CharField(max_length = 200)
price = models.PositiveIntegerField(default=0)
def _str_(self):
return self.name
And I want to create a recommendation list (a list that contains product objects) that allow super user to select products from the built in admin page.
My question is, is creating a separate model (class recommendation(models.Model))and using ForeignKey a correct approach to this situation? Because I do not consider recommendation a model, but I do want super user to be able access and manipulate the list on admin page.
Thanks in advance!
I think the correct approach in this situation would be to set up a recommendation model, but with a many to many relationship. This will allow you to add many products to a specific recommendation, while allowing a product to be used in many recommendations. The set up for this will look something like this:
class Recommendation(models.Model):
products = models.ManyToManyField('Product')
Setting up the model like this will also allow you to explore other features such as adding an owner of a recommendation

Dynamically created proxy models do not have listed permissions on admin site

Here is my models.py:
class Item(models.Model):
# ... some irrelevent fields ...
tags = models.ManyToManyField('Tag')
class Tag(models.Model):
name = models.CharField(max_lenght=30)
category_id = models.IntegerField()
Tag is actually a general-purpose name. Each item has many different type of tags - currently there are four types: team tags, subject tags, admin tags and special tags. eventually there will probably be a few more.
The idea is, they all have basically the same fields, so instead of having like 4 tables with manytomany relationship, and instead of adding a new column for Item whenever adding a new type, everything is called a 'tag' and it's very easy to add new types without any change to the schema.
Now to handle this in the admin.py I'm using dyamically created proxy models (based on this), as such:
def create_modeladmin(modeladmin, model, name = None):
class Meta:
proxy = True
app_label = model._meta.app_label
attrs = {'__module__': '', 'Meta': Meta}
newmodel = type(name, (model,), attrs)
admin.site.register(newmodel, modeladmin)
return modeladmin
class TagAdmin(models.Model):
def queryset(self):
return self.model.objects.filter(category_id = self.cid)
class TeamAdmin(TagAdmin):
cid = 1
class SubjectAdmin(TagAdmin):
cid = 2
# ... and so on ...
create_modeladmin(TeamAdmin, name='Teams', model=Tag)
create_modeladmin(SubjectAdmin, name='Subject', model=Tag)
#... and so on ...
This works great for me. However, different staff members need different editing permissions - one guy shouldn't access admin tags, while the other should only have access to edit subject-tags and team-tags. But as far as the admin site is concerned - the dynamic models do not exist in the permission list, and I can't give anyone permissions regarding them.
i.e. a user given all permissions on the list will still not have access to edit any of the dynamic models, and the only way to let anyone access them at all is to give him a superuser which obviously defies the point
I searched SO and the web and I can't anyone with a similar problem, and the docs don't say anything about this not in the dynamic models section or the proxy models section. so I'm guessing this is a different kind of problem. Any help would be greatly appreciated
UPDATE
So after some research into it, the answer was simple enough. Since permissions in django are objects that are saved to the database, what I needed to do was simple - add the relevent permissions (and create new ContentType objects as well) to the db, and then I could give people specific pemissions.
However, this raised a new question - is it a good convention to put the function that creates the permissions inside create_modeladmin as a find_or_create sort of function (that basically runs every time) or should it be used as an external script that I should run once every time I add a new dynamic model (sort of like how syncdb does it)?
And is there a way to also create the permissions dynamically (which seems to me like the ideal and most fitting solution)?
of course you can create permissions, django have django.contrib.auth.management.create_permissions to do this

Django admin site -- list ForeignKey items as change-list on change page

In (a toy version of) my project, there are Owners who own any number of Objects. My models.py file looks like
class Owner(models.Model)
name = models.CharField(max_length=50)
date_of_birth = models.DateField()
class Object(models.Model)
name = models.CharField(max_length=50)
price = models.models.DecimalField(max_digits=9, decimal_places=2)
owner = models.ForeignKey(Owner)
My question relates to the change page for an Owner on the admin site, e.g.
http://mysite.com/admin/myapp/owner/1/.
Now I know that if I register Object as a TabularInline or a StackedInline, then I get an editable list of the Objects this Owner owns. However, in the real version of my project, an Object has something like 25 fields, not 2, and so neither of those options is really desirable aesthetically.
What I would really like instead is to essentially have a change-list of all the Objects an Owner owns appear on the Owner's change-page. (That way I get a nice compact listing of all the Owner's Objects, and if I need to edit the details of one, I can click on its link and edit it in its own page.) Basically I want the contents of
http://mysite.com/admin/myapp/object/?owner__id__exact=1
to appear within
http://mysite.com/admin/myapp/owner/1/.
Is there a way to do this?
PS: I'm using Django 1.4 and Python 2.7.
You can define what form class and/or fields to use in each InlineModelAdmin using these attributes, and limit the amount of input fields per object that way.

Setting up a weird model in django?

This may be difficult to explain.
I'm a little new to django and the whole idea of models.
Let's say I'm making an article app, where each article has a creator, but other users can edit the article at will. I'm having a little difficult on how to create the models for this.
Firstly,
I extend the user profile with the following:
class UserProfile(models.Model):
#Required field:
user = models.OneToOneField(User)
#Other Fields:
headline = models.CharField()
industry = models.CharField()
article= models.ForeignKey(articleModel.article)
Here is the first place I'm getting confused, do I put the foreignkey field in the user model? My reasoning for it being placed here is because each article can have many editors.
Now here is my article model:
class article(models.Model):
#primary key is already true
creator = models.ForeignKey(userModel.UserProfile)
title = models.CharField()
text = models.TextField()
Over here, I put the ForeignKey field so it would relate back to the creator, because every article has a single creator. (As a side note, I do want to make it so an article can have multiple creators, but I don't know what to do in this scenario).
I'm finding it a bit odd that the UserProfile model is referencing the article model, and the article is referencing it back. Can someone please help me unjumble my brain?
Thank you.
:)
As simple as possible
from django.db.models import *
from django.contrib.admin.models import User
# UserProfile should be provided by django-profiles
class UserProfile(User): # Subclassing user creates an automatic 1-1 called user
headline = CharField()
industry = CharField()
class Article(Model):
# ALWAYS primary key to User, not UserProfile
creator = ForeignKey(User, related_name='articles_created')
contributors = ManyToManyField(User, related_name='articles_edited')
created = DateTime(auto_now_add=True)
modified = DateTimeField(auto_now=True)
title = CharField()
text = TextField()
class Meta:
order = ['created', 'title']
fun stuff:
creator = Article.objects.all()[:1][0].creator.getUserProfile().headline
considder using django-versions if you want to keep track of edits.
class Article(VersionedModel)
EDIT: actually subclasses user
Nothing "weird" here. This is no such a django problem than a database structure problem. You need to read about 1 to 1, 1 to n and n to n relationships between tables.
Do you really need to record all editors of an article ? An article has many editors, and a user can edit many articles, so this is a many to many relationship. Here's how do do it in django.
Perhaps another field in your article model for last editor would provide you with the information you need.
lastEditor = models.ForeignKey(userModel.UserProfile)
If you really want to keep all editors you will need to implement another model which records something like: article_id, editor and edit time (maybe even the article text if you are interested in changes). You could then query this medel based on the current article to obtain a list of all editors.
you could do the same with: article_id and creator to obtain a list of creators of an article (this would replace the article field in your UserProfile class)