Как позволить объектам быть измененными только его создателем - PullRequest
0 голосов
/ 10 февраля 2020

У меня есть проект, в котором пользователь может создать модель Parceiros, и в этой модели есть модель, связывающая все Servicos с этой моделью Parceiros. Проблема в том, что Parceiros должен быть связан с текущим пользователем, так как единственный способ создать объект Parceiros - войти в систему раньше. После этого единственным пользователем, который должен иметь возможность изменять поля Parceiros или Servicos, должен быть текущий пользователь, создавший объект Parceiros. Я прочитал несколько вопросов и попробовал использовать контекстные процессоры, но мне не удалось связать Parceiros с пользователем.

services / models.py

from django.db import models
from phone_field import PhoneField
from datetime import datetime
from django.contrib.auth import get_user_model
from django.template.defaultfilters import slugify


User = get_user_model()

class Parceiros (models.Model):
    user = models.ForeignKey(User, on_delete=models.CASCADE)
    nome = models.CharField(max_length=200)
    endereco = models.TextField(max_length=400, blank=True)
    responsavel = models.CharField(max_length=100)
    tel = PhoneField(max_length=12)
    created_at = models.DateTimeField(auto_now=True)
    updated_at = models.DateTimeField(auto_now_add=True, blank=True)
    ativo = models.BooleanField(default=False)

class Servicos (models.Model):
    tipo = models.CharField(max_length=200)
    objetivo = models.TextField(max_length=500, blank=True)
    parceiro = models.ForeignKey(Parceiros, on_delete=models.CASCADE)
    preco = models.DecimalField(max_digits=9, decimal_places=2, blank=True)
    telefone = PhoneField(max_length=12, default='21968151502')

def get_image_filename(instance, filename):
    tipo = instance.services.tipo
    slug = slugify(tipo)
    return "servicos_imagens/%s-%s" % (slug, filename)

class Imagens (models.Model):
    servicos = models.ForeignKey(Servicos, on_delete=models.CASCADE)
    imagem = models.ImageField(upload_to=get_image_filename)


services / views. py

from django.shortcuts import render, redirect
from .models import Servicos, Parceiros, Imagens
from django.views.generic import UpdateView, DetailView, ListView
from .forms import ParceirosForm, ServicosForm, ImagensForm
from django.contrib.auth.decorators import login_required
from django.contrib.auth.context_processors import auth


def home_view(request):
    serv = Servicos.objects.all()
    context = {'serv': serv }
    return render (request, 'home.html', context)


@login_required
def parceiros_create(request):
    if request.method =='POST':
        form = ParceirosForm(request.POST)
        Parceiros.user = auth.user
        if form.is_valid():
            parceiro = form.save(commit=False)
            parceiro.save()
        return redirect('home2')
    else:
        form = ParceirosForm()
    context = {
        'form': form,
    }
    return render (request, 'parceiroform.html', context)


def parceirosview(request):
    user = Servicos.parceiro
    serv = Servicos.objects.get(parceiro=user)
    context = {'serv': serv}
    return render(request, 'parceiro.html', context)


class ServicoView(DetailView):
    model = Servicos



class ServicoUpdate(UpdateView):
    model = Servicos
    template_name = 'servicoform.html'

services / forms.py:

from django import forms
from .models import Servicos, Imagens, Parceiros
from phone_field import PhoneField

class ParceirosForm(forms.ModelForm):
    class Meta:
        prefix = 'parceiro'
        model = Parceiros
        fields = ['nome', 'endereco', 'responsavel', 'tel']



class ServicosForm(forms.ModelForm):
    tipo = forms.CharField(max_length=200)
    objetivo = forms.CharField(max_length=500)
    preco = forms.DecimalField(max_digits=9, decimal_places=2)
    telefone = PhoneField(max_length=12)

    class Meta:
        prefix = 'service'
        model = Servicos
        fields = ['tipo', 'objetivo', 'preco', 'telefone']


class ImagensForm(forms.ModelForm):
    imagem = forms.ImageField(label='image')

    class Meta:
        model = Imagens
        fields = ['imagem']


1 Ответ

1 голос
/ 10 февраля 2020

Parceiros является классом, поэтому Parceiros.user = auth.user ничего не делает.

При сохранении формы вам следует присвоить user фактическому экземпляру модель, которую вы сохраняете:

if form.is_valid():
    parceiro = form.save(commit=False)
    parceiro.user = request.user  # assuming user is a FK field on Parceiros
    parceiro.save()

Обратите внимание, что вы должны использовать request.user (не auth.user), который является текущим вошедшим пользователем.

Для UpdateView s, вам нужно только изменить queryset, чтобы обеспечить возможность изменения только экземпляров, принадлежащих этому пользователю:

# inside class ServicoUpdate
# Servico is related to User via the Parceiros model

def get_queryset(self):
     return super().get_queryset().filter(parceiro__user=self.request.user)

# inside class ParceiroUpdate

def get_queryset(self):
     return super().get_queryset().filter(user=self.request.user)

И аналогично для любого другого представления, для которого требуется ограничить доступ только текущим вошедшим в систему экземпляры пользователя, если используется представление на основе классов, переопределяют get_queryset().

...