首页 > 解决方案 > 如何让对象被他的创造者改变

问题描述

我有一个项目,用户可以在其中创建模型 Parceiros,并且在该模型中是一个将所有 Servicos 链接到该模型 Parceiros 的模型。问题是 Parceiros 应该链接到当前用户,因为创建 Parceiros 对象的唯一方法是之前登录。之后,应该能够更改 Parceiros 字段或 Servicos 的唯一用户应该是创建 o Parceiros 对象的当前用户。我已经阅读了一些问题并尝试使用上下文处理器,但没有设法将 Parceiros 链接到用户。

服务/模型.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)


服务/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'

服务/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']


标签: pythondjangopython-3.xdjango-modelsdjango-forms

解决方案


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(not auth.user) 这是当前登录的用户。

对于UpdateViews,您只需要更改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().


推荐阅读