django 用户无法在页面中创建对象

qq24tv8q  于 2023-06-07  发布在  Go
关注(0)|答案(2)|浏览(193)

我做了一个程序,用户可以通过在创建自己的帐户后将其输入系统来跟踪他们的支出。系统要求用户填写四个字段:客户类别价格月份。我希望第一个字段(客户)自动填充登录用户的用户名,这样用户就不必从所有可用客户中进行选择。
但是,我遇到了一个问题,用户无法在系统中创建对象。我只能通过管理 Jmeter 板创建对象。当我试图在页面上创建一个对象时,它会抛出一条错误消息,说:

RelatedObjectDoesNotExist at / User has no customer.

我怀疑这个问题与以下事实有关:用户是在管理页面的“用户”下的“身份验证和授权”部分添加的,而不是由我的应用在“客户”下创建的,旁边是存储对象的“财务”部分。
总结我的两个主要问题:
1.我希望第一个字段自动填充登录用户的用户名。
1.我希望用户能够直接从页面创建对象,就像过去没有发生这个问题时一样。
谢谢你的帮助
models.py:

class Customer(models.Model):
    user = models.OneToOneField(User, null=True, on_delete=models.CASCADE)
    name = models.CharField(max_length=200, null=True)
    email = models.CharField(max_length=200, null=True, blank=True)
    date_created = models.DateTimeField(auto_now_add=True, null=True)

    # def __str__(self):
    #     return self.name #I don't now if it's correct

class Finance(models.Model):
    expenses_category = [
        ("Saving", "Saving"),
        ("Food", "Food"),
        ("Bills", "Bills"),
        ("Rent", "Rent"),
        ("Extra", "Extra"),
    ]

    expenses_month = [
        ("January", "January"),
        ("February", "February"),
        ("March", "March"),
        ("April", "April"),
        ("May", "May"),
        ("June", "June"),
        ("July", "July"),
        ("August", "August"),
        ("September", "September"),
        ("October", "October"),
        ("November", "November"),
        ("December", "December"),
    ]

    customer = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
    category = models.CharField(choices=expenses_category, max_length=200)
    price = models.IntegerField()
    month = models.CharField(choices=expenses_month, max_length=200)

views.py:

@csrf_exempt
def registerPage(request):
    if request.user.is_authenticated:
        return redirect('home')
    else:
        form = CreateUserForm()
        if request.method == 'POST':
            form = CreateUserForm(request.POST)
            if form.is_valid():
                # form.instance.user = request.user
                user = form.save()
                username = form.cleaned_data.get('username')

                group = Group.objects.get(name='customer')
                user.groups.add(group)

                messages.success(request, 'Account was created for ' + username)

                return redirect('login')

        context = {'form': form}
        return render(request, 'app_finance/register.html', context)

def loginPage(request):
    username = None
    if request.user.is_authenticated:
        username = request.user.customer
        return redirect('home')
    else:
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')

            user = authenticate(request, username=username, password=password)

            if user is not None:
                login(request, user)
                return redirect('home')
            else:
                messages.info(request, 'Username or password incorrect.')

        context = {}
        return render(request, 'app_finance/login.html', context)

def logoutUser(request):
    logout(request)
    return redirect('login')

def userPage(request):
    return render(request, 'app_finance/user.html')

@login_required(login_url='login')
def homeView(request):
    # customer = Customer.objects.get(id=pk) (not sure#)
    username = None
    items = Finance.objects.filter(customer_id=request.user.id)
    form = FinanceForm(initial={'customer': User})
    if request.method == 'POST':
        username = request.user.customer
        form = FinanceForm(request.POST)  # initial={'customer': user}
        if form.is_valid():
            form.save()
            return HttpResponseRedirect('/')
    else:
        form = FinanceForm()
        return render(request, 'app_finance/home.html', {'form': form, 'items': items})

forms.py:

class CustomerForm(ModelForm):
    class Meta:
        model = Customer
        fields = '__all__'
        exclude = ['user']

class CreateUserForm(UserCreationForm):
    class Meta:
        model = User
        fields = ['username', 'email', 'password1', 'password2']

class FinanceForm(ModelForm):
    class Meta:
        model = Finance
        fields = '__all__'

templates/home.html:

<div>
    <span>Hello, {{ request.user }}</span> <br>
    <span><a class="hello-msg" href="{% url 'logout' %}">Logout</a></span>
</div>

<form action="" method="post">
    {% csrf_token %}
    {{ form }}
    <!-- {{ form }} -->

    <input type="submit" value="Submit">
</form>

<br>
<div class="row">
    <div class="col-md">
        <div class="card card-body">
            <h1>Expenses</h1>
        </div>
        <div class="card card-body">
            <table class="table">
                <tr>
                    <th>User</th>
                    <th>Category</th>
                    <th>Price</th>
                    <th>Month</th>
                </tr>
                {% for i in items %}
                    <tr>
                        <td>{{ i.customer }}</td>
                        <td>{{ i.category }}</td>
                        <td>{{ i.price }}</td>
                        <td>{{ i.month }}</td>
                        <td>&nbsp;&nbsp;</td>
                        <td><a class="btn btn-sm btn-info" href="">Update</a></td>
                        <td><a class="btn btn-sm btn-danger" href="">Delete</a></td>
                    </tr>
                {% endfor %}
            </table>
        </div>
    </div>
</div>

再次感谢你的帮助。

jhdbpxl9

jhdbpxl91#

正如你在评论中所说:
这就是金融模型。我想在FinanceForm中排除'customer',这样用户就不必选择它的用户名,但我让它这样,这样我就可以检查它是否正确地制作表单,选择登录的用户,到目前为止它还没有这样做。
允许用户在创建模型时选择自己是不智能的,因为有人可能会使用其他用户来创建Finance模型的对象,要解决这个问题,您必须通过删除'__all__'来更改FinanceForm并指定您希望用户看到的字段:

class FinanceForm(ModelForm):
    class Meta:
        model = Finance
        fields = ['month', 'price', 'category']

当你说:你想提交一个Finance模型,但是你没有在你的问题中添加这样做的视图,所以你可以使用函数基视图或类基视图来完成:
使用函数基视图:

def create_finance(request):
    if request.method == 'POST':
        price = request.POST['price']
        month = request.POST['month']
        category = request.POST['category']
        form = FinanceForm(request.POST)
        if form.is_valid():
            new_finance_object = Finance.objects.create(customer=request.user, price=price, month=month, category=category)
            new_finance_object.save()
            return redirect('home')
    else:
        form = FinanceForm()
    return render(request, 'create_finance.html', {'form':form})

可以使用类基视图:

from django.views.generic import CreateView 

class CreateFinance(CreateView):
    model = Finance
    form_class = FinanceForm
    template_name = 'create_finance.html'

    def form_valid(self, form):
        form.instance.customer = self.request.user
        return super(CreateFinance, self).form_valid(form)
4zcjmb1e

4zcjmb1e2#

这是我找到的解决方案,工作也很完美。我做了两个改变:

  1. views.py:
@login_required(login_url='login')
def homeView(request):
    items = Finance.objects.filter(customer=request.user).order_by(Cast('month', IntegerField())).reverse()

    if request.method == 'POST':
        form = FinanceForm(request.POST, request=request)  # Pass the request object to the form
        if form.is_valid():
            finance_obj = form.save(commit=False)
            finance_obj.customer = request.user
            finance_obj.save()
            return redirect('home')
    else:
        form = FinanceForm(request=request)  # Pass the request object to the form

    context = {'form': form, 'items': items}
    return render(request, 'app_finance/home.html', context)
  1. forms.py
class FinanceForm(ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')  # Retrieve the request object
        super().__init__(*args, **kwargs)
        self.fields['customer'].initial = self.request.user

相关问题