Django models in file sharing system - django

models.py :
class Document(models.Model):
docfile = models.FileField(upload_to='documents/%Y/%m/%d')
user = models.ForeignKey(User, null=False, blank= False)
I have created a model for file upload as shown above. docfile is the field that represents file to be uploaded and user field stores the name of the user that is uploading the file.I want the additional fields so that file uploaded is visible to the ones with whom it has been shared. Tell me the fields for achieving the sharing task.

You would another field which has a foreign key to Django User Model.
user = models.ForeignKey(User, null=False, blank= False)
then whenever you want to fetch documents based on the logged in user, you would use this
docs = Document.objects.filter(user=request.user)

In models.py
users = model.ManyToMany(User)
this should work, although am not so sure. But feel free to let me know if you by chance run into any problem
In views.py
docs = Document.users.filter(username=request.user.username)

Related

Django + DRF Create file from json value

I'm building a part of django+drf app that will create article models from the given JSON request. Example of request:
{
"title":"title"
"author":"author"
"text":"possible huge amount of text"
...
}
Article model:
class Article(models.Model):
title = models.CharField(max_length=config.ARTICLE_TITLE_MAX_LENGTH)
views = models.IntegerField(default=0)
author = models.ForeignKey(User, related_name='articles', on_delete=models.CASCADE)
date_created = models.DateTimeField('Date created', auto_now_add=True)
published = models.BooleanField(default=False)
text = models.FileField(upload_to='content/articles_storage/', null=True)
This data is processed by article serializer
class ArticleSerializer(serializers.ModelSerializer):
# content = serializers.CharField() ???
class Meta:
model = Article
# fields = ['id','title','views','date_created','content']
fields = ['id','title','views','date_created','text']
Serializer expects text field to be a file, however, it is gonna be plain text, so when the user makes a POST request to the server, I want the server to validate the text, create a file from this text, save it to the folder content/article_storage
When the user makes a GET request, I want the server to read that file and create a JSON response like above.
My question is what is the best way to do this? I definitely don't want to use django's TextField. Also I'm wondering if I actually need FieldFile, maybe it's better to store the text in a file with the name = article id?

How to add custom filed to Django User Model

I am working on the project using django 1.9.
I need to add a field to the user model 'Auth_user' table, the field which i want can be another primary key and act here as foreign key in the 'auth_user'.
I searched a lot but fails. Can any buddy provide me some example how to achieve this like how to to add fields to 'auth_user'
You can substitute the user model entirely as described in doc. Here is an example:
AUTH_USER_MODEL = 'myapp.MyUser'
to your settings.py, and add following to your model:
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
another_object = models.ForeignKey(OtherModel..
just make a new moel with a user foreign key
class Post (models.Model):
title = models.CharField(max_length=80)
slug= models.SlugField(unique=True)
content = models.TextField()
user_creator = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
there you can use as primary key the id of the post, or the slug (unique), and it can be linked to a user, if you need one to one relationship see this or many to many relationship see this
Maybe you just need to extend de model user
https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#extending-the-existing-user-model

Adding/deleting fields in the same ModelForm django

I have little experience in django so I would really appreciate your help!
In general, I have created a ModelForm which depending on the users who is logged in, he changes some values in the field. So consider that this form is being edited about 5 times by 5 different users.
I would like to show a specific field in the template (and view) only when the third user is logged in.
My model is :
class Task(models.Model):
Taskdetails = models.CharField(max_length=500, null=True)
asset = models.ForeignKey('Asset', null=True)
failure = models.ForeignKey('Failure', null=True)
cause = models.ForeignKey('Cause', null=True)
Created_task_date = models.DateTimeField(default=timezone.now, null=True)
employee = models.ForeignKey("auth.User", null = True)
and also i have created this ModelForm
class Meta:
model = Task
fields = ('Taskdetails', 'asset', 'failure', ,'employee','cause',)
Also I have 5 edititions of the TaskForm in which is user edits something.
The thing I am trying to do is to show the cause field only in the third form.
I tried to exclude the value but nothing apperas.
If i include the field cause (just like above), I must "pass" it in the template in order to be edited from the first user (otherwise the task_form is not saved)
I hope I became clear.
I would really appreciate your help.

Django user audit

I would like to create a view with a table that lists all changes (created/modified) that a user has made on/for any object.
The Django Admin site has similar functionality but this only works for objects created/altered in the admin.
All my models have, in addition to their specific fields, following general fields, that should be used for this purpose:
created_by = models.ForeignKey(User, verbose_name='Created by', related_name='%(class)s_created_items',)
modified_by = models.ForeignKey(User, verbose_name='Updated by', related_name='%(class)s_modified_items', null=True)
created = CreationDateTimeField(_('created'))
modified = ModificationDateTimeField(_('modified'))
I tried playing around with:
u = User.objects.get(pk=1)
u.myobject1_created_items.all()
u.myobject1_modified_items.all()
u.myobject2_created_items.all()
u.myobject2_modified_items.all()
... # repeat for >20 models
...and then grouping them together with itertool's chain(). But the result is not a QuerySet which makes it kind of non-Django and more difficult to handle.
I realize there are packages available that will do this for me, but is it possible to achieve what I want using the above models, without using external packages? The required fields (created_by/modified_by and their timefields) are in my database already anyway.
Any idea on the best way to handle this?
Django admin uses generic foreign keys to handle your case so you should probably do something like that. Let's take a look at how django admn does it (https://github.com/django/django/blob/master/django/contrib/admin/models.py):
class LogEntry(models.Model):
action_time = models.DateTimeField(_('action time'), auto_now=True)
user = models.ForeignKey(settings.AUTH_USER_MODEL)
content_type = models.ForeignKey(ContentType, blank=True, null=True)
object_id = models.TextField(_('object id'), blank=True, null=True)
object_repr = models.CharField(_('object repr'), max_length=200)
action_flag = models.PositiveSmallIntegerField(_('action flag'))
change_message = models.TextField(_('change message'), blank=True)
So, you can add an additional model (LogEntry) that will hold a ForeignKey to the user that changed (added / modified) the object and a GenericForeignKey (https://docs.djangoproject.com/en/1.7/ref/contrib/contenttypes/#generic-relations) to the object that was modified.
Then, you can modify your views to add LogEntry objects when objects are modified. When you want to display all changes by a User, just do something like:
user = User.objects.get(pk=1)
changes = LogEntry.objects.filter(user=user)
# Now you can use changes for your requirement!
I've written a nice blog post about that (auditing objects in django) which could be useful: http://spapas.github.io/2015/01/21/django-model-auditing/#adding-simple-auditing-functionality-ourselves

Relationships with Django and rest framework add replace fields

My user object with rest framework has an avatar_id and a cover_id. But Instead of displaying that to the API, I want it to be the actual avatar URL and cover URL already.
My User model:
avatar_id = models.IntegerField()
cover_id = models.IntegerField()
My UserAvatar model:
id = models.IntegerField(primary_key=True)
user_id = models.IntegerField()
file_id = models.IntegerField()
My Files model:
id = models.IntegerField(primary_key=True)
filename = models.CharField(max_length=255)
Same concept with UserCover.
How do I remove the avatar_id from the results of /users/ and add a avatar field with the actual avatar filename?
I'm not sure I understand your question correctly, but here what I think the problems are. Reading your question, I assumed that you are a beginner, so I answered as such. Sorry if it's not the case.
You don't need to add the id fields, it's done automatically by Django because all tables need a primary key. You define a PK only when you need to name it something else than 'id'.
You should really read the Django tutorial which explains how to define models. User.cover_id and UserAvatar.file_id should be defined as ForeignKey. If you don't know what a foreign key is, then stop playing with Django and read a database tutorial before.
There's already a model and a set of classes to manage your users in Django. You should use them. For example, a "user profile" is the right way to extend the user model.
If you force the users to choose one avatar in a set of predefined avatars, then what you want to do is ok. If the users can choose any avatar (upload), then you should use OneToOneField or put it directly in the user model (or profile).
I don't know what is a UserCover, but here's what your models could look like:
from django.contrib.auth.models import User
class UserProfile(models.Model):
# Link to Django normal User (name, email, pass)
user = models.ForeignKey(User, unique=True)
# Any information that a user needs, like cover, wathever that is, age, sexe, etc.
avatar = models.CharField(max_length=255)
Or like this if a will be reused often :
class Avatar(models.Model):
# name = ...
# description = ...
path = models.CharField(max_length=255)
class UserProfile(models.Model):
user = models.ForeignKey(User, unique=True)
avatar = models.ForeignKey(Avatar, unique=True)
# other data