I'm creating a site where users can upload files. I have my upload form working, and it correctly associates the current user with the uploaded file. Once it's uploaded however, I would like the User Profile model to update the number of files uploaded for that specific user. I'm using django-allauth with a custom admin model.
models.py (works to recognize current user)
class ConfigFiles(models.Model):
user = models.ForeignKey(
settings.AUTH_USER_MODEL, blank=True, null=True)
Printer = models.CharField(_('Printer Model'),
max_length=100, blank=True, null=True, unique=False, help_text="Something like 'i3'")
printerbrand = models.CharField(_('Printer Brand'),
max_length=100, blank=True, null=True, unique=False, help_text="Something like 'Prusa'")
Plastic = models.CharField(_('Plastic'),
max_length=40, blank=True, null=True, unique=False, help_text="Something like 'ABS' or 'Nylon'")
HDConfig = models.FileField(_('High Detail, Slow Speed'),
upload_to=UploadedConfigPath, validators=[validate_file_extension], help_text="Displayed as HD on Infinity-Box")
LDConfig = models.FileField(_('Fast speed, Low Detail'),
upload_to=UploadedConfigLDPath, validators=[validate_file_extension], help_text="Displayed as FAST on Infinity-Box")
pub_date = models.DateTimeField(_('date_joined'),
default=timezone.now)
And here's my custom admin models.py (doesn't auto update configuploaded)
class UserProfile(models.Model):
user = models.OneToOneField(DemoUser, primary_key=True, verbose_name='user', related_name='profile')
avatar_url = models.CharField(max_length=256, blank=True, null=True)
configuploaded = models.IntegerField(_('Number of uploaded Config files'), default=0, unique=False)
filesuploaded = models.IntegerField(_('Number of uploaded STL files'), default=0, unique=False)
dob=models.DateField(verbose_name="dob", blank=True, null=True)
def __str__(self):
return force_text(self.user.email)
class Meta():
db_table = 'user_profile'
EDIT 1
Here's view.py.
@login_required
def uplist(request):
if request.method == 'POST':
form = ConfigUpload(request.POST, request.FILES)
if form.is_valid():
comment = form.save(commit=False)
comment.user = request.user
#newdoc = ConfigFiles(HDConfig=request.FILES['HD file'])
comment.save()
messages.add_message(request, messages.SUCCESS, "Configuration added")
# Redirect to the document list after POST
return HttpResponseRedirect(reverse_lazy('list'))
else:
form = ConfigUpload() # A empty, unbound form
print (request.user.first_name)
# Load documents for the list page
documents = ConfigFiles.objects.all()
# Render list page with the documents and the form
return render(
request,
'visitor/configupload.html',
{
'documents': documents,
'form': form,
}
)
Ideally, whenever the user uploads a file the configuploaded variable increase correspondingly. Is there a simple way to do this within models or should I do if from my views.py?
Theres a few ways to solve this, how best to go about it depends on your use case. In my current site I use a mix of properties and signals to acheive this functionality.
Using a property - less db writes works & even if you execute bulk deletes on a model, but generates a query everytime you display it.
class UserProfile(models.Model):
#your stuff
def _get_uploaded_files(self):
return ConfigFiles.objects.filter(some_appropriate_filter).count()
uploaded_files = property(_get_uploaded_files)
Override the save method to increment your field:
class ConfigFiles(models.Model):
#your model definition here
def save(self, *args, **kwargs):
super(ConfigFiles, self).save(*args, **kwargs)
self.user.filesuploaded += 1
You can also use the postsave signals as per Atul Yadav's answer. However IMO they are somewhat less clear (because you end up defining functionality outside of the model) although they are useful if you need to do several things