#django #django-admin #action
#django #django-администратор #Экшен
Вопрос:
Я создаю приложение Django для загрузки файлов. Я хотел бы иметь возможность подсчитывать количество файлов, которые есть у пользователей и которые одобрены. У меня есть модель с логическим полем «одобрено». Эта модель находится в admin.py .
В admin.py
from django.contrib import admin
from .models import FileModel
from .forms import FileForm
class FileModelAdmin(admin.ModelAdmin):
form = FileForm
fields = ('title', 'description', 'categories', 'pub_date', 'submitted_date', 'author', 'user', 'approved', 'upload', 'vote')
# pass
list_display = ['title', 'approved', 'author', 'user', 'categories', 'description', 'pub_date', 'submitted_date', 'upload', 'vote']
admin.site.register(FileModel, FileModelAdmin)
Я хотел бы, чтобы целое число в другой модели ‘new_user_model’, которое находится в другом приложении, увеличивало целочисленное поле ‘files’ на единицу, когда файл утверждается на сайте администратора. Таким образом, я мог отслеживать, сколько файлов было одобрено для каждого пользователя.
class NewUserModel(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
# user = models.ForeignKey(User)
files = models.IntegerField(default=0)
Модель для файлов,
class FileModel(models.Model):
title = models.CharField(max_length=100)
description = models.CharField(max_length=255)
pub_date = models.DateTimeField('date published')
submitted_date = models.DateTimeField('date submitted')
author = models.CharField(max_length=255)
user = models.ForeignKey(User, default=6)
approved = models.BooleanField(default=False)
upload = models.FileField().....................
...................................................
Поэтому я хочу, чтобы поле files в new_user_model увеличивалось на единицу, когда файл «одобрен» и нажата кнопка сохранения на сайте администратора. Кроме того, если флажок «одобрено» снят, мне нужно, чтобы поле «файлы» уменьшилось на единицу.
Как это можно сделать?
Обновлено:
В конечном счете, я хотел бы иметь возможность отображать количество файлов, которые пользователь имеет на сайте.
Спасибо,
Комментарии:
1. Вы уверены, что не предпочли бы иметь
approved_by
ForeignKey в FileModel? Таким образом, вы можете подсчитать, сколько файлов кто-то одобрил, и узнать, какие файлы они одобрили.2. Хорошо, это звучит как правильный способ сделать это. Значит, это будет внешний ключ для пользователя?
3. Вы хотите сказать, что каждый файл может быть одобрен несколько раз разными пользователями? Если только один человек одобряет один раз, вам понадобится ForeignKey для пользователя, если несколько пользователей могут одобрить файл, вы хотите, чтобы поле ManyToMany для пользователя.
4. Администратор — это просто поле в модели пользователя — если вы сделаете действие доступным только на сайте администратора, только администраторы смогут одобрить.
5. Вы пытались добавить действия администратора в соответствии с моим ответом? Они находятся только на сайте администратора.
Ответ №1:
Вы можете добавить пользовательское действие администратора, которое помечает файлы как одобренные. Им передается объект запроса, который вы можете использовать для получения вашего NewUserModel
. (Возможно, вы захотите убрать слово «Модель» из названий ваших моделей, это кажется немного излишним, но я полагаю, что это личный вкус 🙂
class FileModelAdmin(admin.ModelAdmin):
form = FileForm
fields = ('title', 'description', 'categories', 'pub_date', 'submitted_date', 'author', 'user', 'approved', 'upload', 'vote')
# ....
actions = ['approve_files']
def approve_files(self, request, queryset):
# Queryset can be greater than 1
queryset.update(approved=True)
user = request.user
# I keep wanting to put underscores in...
user_files_count = user.newusermodel.files
# Get the amount of Files in the query, may be more than one
user.newusermodel.files = user_files_count queryset.count()
user.newusermodel.save()
При этом, если вы действительно хотите отслеживать, кто что одобрил:
class FileModel(models.Model):
title = models.CharField(max_length=100)
# ...
approved_by = models.ForeignKey('auth.User')
тогда действие администратора, описанное выше, будет просто:
def approve_files(self, request, queryset):
# Queryset can be greater than 1
queryset.update(approved_by=request.user)
и вы могли бы получить количество файлов пользователя, выполнив:
user = Users.objects.get(id=some_id)
file_count = user.filemodel.all().count()
Комментарии:
1. Используя только первый указанный вами блок кода, я получаю сообщение об ошибке «RelatedObjectDoesNotExist в /adminfileuploader/filemodel/ User не имеет newusermodel». и проблема с «user_files_count = user.newusermodel . файлы»
2. Я попробовал это с подчеркиванием «new_user_model», но безуспешно,
3. Я забыл, из crudapp.models импортировать NewUserModel
4. Все еще нужно кое-что исправить, но сейчас он работает достаточно, чтобы с ним можно было поиграть. Я опубликую сообщение, если и когда добьюсь некоторого прогресса. Спасибо
Ответ №2:
У меня наконец-то появился шанс завершить это?
from django.contrib import admin
from .models import FileModel
from django.contrib.auth.models import User
from .forms import FileForm
from crudapp.models import NewUserModel
#from django.db import models
from django.core.exceptions import PermissionDenied
from django.contrib import admin
from django.contrib.admin.actions import delete_selected as delete_selected_
# see https://gist.github.com/rudyryk/4190318
# overrides and recreates delete_selected
def delete_selected(modeladmin, request, queryset):
if not modeladmin.has_delete_permission(request):
raise PermissionDenied
if request.POST.get('post'):
for obj in queryset:
obj.delete()
else:
return delete_selected_(modeladmin, request, queryset)
delete_selected.short_description = "Delete selected objects"
class FileModelAdmin(admin.ModelAdmin):
form = FileForm
fields = ('title', 'description', 'categories', 'pub_date', 'submitted_date', 'author', 'user', 'approved', 'upload', 'vote')
# pass
list_display = ['title', 'approved', 'author', 'user', 'categories', 'description', 'pub_date', 'submitted_date', 'upload', 'vote']
actions = ['approve_files', 'delete_selected']
def approve_files(self, request, obj):
for qs in obj:
print "run number..."
author = qs.author
adminApproved = qs.approved # approved status on admin site
userInstance = User.objects.get(username=author)
id = qs.id
item = FileModel.objects.get(pk=id)
approved = item.approved # approved status in FileModel
id = userInstance.id
item = NewUserModel.objects.get(user_id=id)
print "existentialism"
print "approved: %s" %(approved)
print "adminApproved: %s" %(adminApproved)
if(approved == False):
item.files = 1
item.save()
obj.update(approved = True)
#NewUserModel.save()
#obj.save()
def save_model(self, request, obj, form, change):
id = obj.id
item = FileModel.objects.get(pk=id)
# Test if file 'approved' has been changed on admin site
if(item.approved != obj.approved):
author = obj.author
userInstance = User.objects.get(username=author)
id = userInstance.id
item = NewUserModel.objects.get(user_id=id)
if(obj.approved == True):
item.files = 1
item.save()
else:
item.files -= 1
item.save()
obj.save()
def delete_model(self, request, queryset):
print "we are inside delete_model()"
author = queryset.author
userInstance = User.objects.get(username=author)
id = queryset.id
item = FileModel.objects.get(pk=id)
approved = item.approved # approved status in FileModel
#filename=obj.profile_name ".xml"
#os.remove(os.path.join(obj.type,filename))
id = userInstance.id
item = NewUserModel.objects.get(user_id=id)
# -1 for file in filemodel only if approved
if approved == True:
item.files -= 1
item.save()
print "inner part of delete_model()"
queryset.delete()
# The 'Delete selected' action
def delete_selected(self, request, queryset):
print "we are inside delete_selected()"
for obj in queryset:
author = obj.author
adminApproved = obj.approved # approved status on admin site
userInstance = User.objects.get(username=author)
id = obj.id
item = FileModel.objects.get(pk=id)
approved = item.approved # approved status in FileModel
id = userInstance.id
item = NewUserModel.objects.get(user_id=id)
# For the case where a file is deleted but was approved yet
if approved == True:
item.files -= 1
print "inner part of delete_selected()"
item.save()
print "running for each iteration of obj"
queryset.delete()
admin.site.register(FileModel, FileModelAdmin)