Django中基于登录用户名实现数据新增/覆写功能的问题排查
Got it, let's break down what's going wrong and fix this step by step. The main issue is your current code doesn't check if the logged-in user already has an OrderItem record before saving—so it always creates a new entry instead of updating the existing one. Plus, your UpdateOrderView has some critical bugs that prevent it from working as intended.
Key Problems in Your Current Code
OrderView: No check for existing user records—just saves the form directly every time, leading to duplicates.UpdateOrderView:username = user.is_authenticatedis wrong—is_authenticatedreturns a boolean, not the actual username.- You're trying to use a
pkURL parameter, but your logic relies onusername, so the pk is irrelevant here. - Form initialization for updates is incorrect.
Step-by-Step Fix
1. Add Login Requirement (Critical)
First, make sure only logged-in users can access these views. Import Django's login decorator and apply it to your views.
2. Rewrite OrderView to Handle Create/Update
We'll use Django's get_or_create() method to fetch the existing order for the logged-in user (or create a new one if none exists), then bind it to the form. This way, submitting the form will either update the existing record or save a new one.
3. Secure the Form (Optional but Recommended)
Prevent users from modifying the username field by excluding it from the form—we'll set it programmatically to the logged-in user's username to avoid tampering.
Updated Code
views.py
from django.contrib.auth.decorators import login_required from django.shortcuts import render, redirect from .models import OrderItem from .forms import OrderForm # Make sure you have this imported @login_required # Ensures only logged-in users can access this def OrderView(request): # Get the current logged-in user's username current_user = request.user # Fetch existing order for the user, or create a blank one if none exists order, was_created = OrderItem.objects.get_or_create(username=current_user.username) # Initialize form with the existing order (or new blank instance) form = OrderForm(instance=order) if request.method == 'POST': # Bind POST data to the existing order instance form = OrderForm(request.POST, instance=order) if form.is_valid(): # Save the form—this will update the existing record or create a new one form.save() return redirect('order-page') # Redirect back to the order page context = {'form': form} # Note: Remove the leading slash from the template path—it should be relative to your templates folder return render(request, 'order_info.html', context) # If you still need a dedicated update view (optional, since OrderView handles both now) @login_required def UpdateOrderView(request): current_user = request.user try: order = OrderItem.objects.get(username=current_user.username) except OrderItem.DoesNotExist: # If no order exists for the user, redirect to create it return redirect('order-page') if request.method == 'POST': form = OrderForm(request.POST, instance=order) if form.is_valid(): form.save() return redirect('order-page') else: form = OrderForm(instance=order) context = {'form': form} return render(request, 'order_info.html', context)
forms.py (Add this if you haven't already)
from django import forms from .models import OrderItem class OrderForm(forms.ModelForm): class Meta: model = OrderItem # Exclude username so users can't edit it—we set it via the view exclude = ['username'] # Or specify fields explicitly if you prefer: # fields = ['first_name', 'last_name', 'vendor_name', 'menu_name', 'note']
urls.py (Adjust to remove unnecessary pk parameter)
from django.urls import path from . import views urlpatterns = [ path("order_info", views.OrderView, name="order-page"), # If you keep the update view, remove the pk since we use username path("order_update", views.UpdateOrderView, name="order-update"), ]
Why This Works
get_or_create(): This method safely retrieves the existingOrderItemfor the logged-in user, or creates a new blank instance if none exists.- Form Binding: By passing
instance=orderto the form, Django knows to update that specific record instead of creating a new one whenform.save()is called. - Login Protection: The
@login_requireddecorator ensures we always have a valid logged-in user to fetch the username from.
内容的提问来源于stack exchange,提问作者D C

